Compare commits
157 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
34a20d3475 | ||
|
d8af8fb70a | ||
|
85de91411e | ||
|
c1356549ec | ||
|
f34617b7db | ||
|
71628dcdd2 | ||
|
2ef2d01fc0 | ||
|
bc9757f7b9 | ||
|
3341a29421 | ||
|
5dc7de9ded | ||
|
00359591b5 | ||
|
624b06fe85 | ||
|
4921b43e1b | ||
|
7b9bb93103 | ||
|
932b2e1d79 | ||
|
9b01aada15 | ||
|
da059a3c9c | ||
|
acefe20fc0 | ||
|
efac958ea0 | ||
|
ae686de0ab | ||
|
dc855fa6ef | ||
|
97f606a314 | ||
|
2e45db73e5 | ||
|
1a017ceed0 | ||
|
a686b8939e | ||
|
e03b492c1d | ||
|
c3587b4411 | ||
|
b3fbfbb3ad | ||
|
83a0e74a88 | ||
|
467d3e48cd | ||
|
45f9b1d9e2 | ||
|
da024251de | ||
|
00887b7409 | ||
|
1985b51f98 | ||
|
fce6f58eb0 | ||
|
18a51e7c26 | ||
|
5f62a24f08 | ||
|
1375fc4fbc | ||
|
3739fcc4ac | ||
|
2c69d7e145 | ||
|
173643eb37 | ||
|
6c2b475213 | ||
|
14ecacf811 | ||
|
c9ec52a7c9 | ||
|
5c19aab68c | ||
|
f78fa04842 | ||
|
aab9cb8bed | ||
|
b5582126ba | ||
|
4d37cc9267 | ||
|
760c683e3e | ||
|
1be38bdb76 | ||
|
a253ec5de5 | ||
|
bfaf8ea7d8 | ||
|
001a963b04 | ||
|
e5249cf4b3 | ||
|
04a0560339 | ||
|
6eb2ca001c | ||
|
1677cfc318 | ||
|
a7b5057f9e | ||
|
35d4ab4cfc | ||
|
4c3a511551 | ||
|
bd70771cf5 | ||
|
73d21dbca9 | ||
|
67f62970d7 | ||
|
54eef21574 | ||
|
bbba502ba7 | ||
|
9ceeb48562 | ||
|
8ad81f244f | ||
|
cfed96504b | ||
|
1fb3c04c37 | ||
|
edb841c38c | ||
|
9a7d6a007b | ||
|
e58d229abc | ||
|
f84d221857 | ||
|
26ed24d339 | ||
|
73caf6074b | ||
|
89f7d38a77 | ||
|
d1281b0346 | ||
|
53008131c6 | ||
|
c9b5c908a0 | ||
|
dcefdfab33 | ||
|
4357eec04f | ||
|
9d8ccd5a67 | ||
|
d24f91afc1 | ||
|
84d8a396f0 | ||
|
9917926a43 | ||
|
b7d2f79462 | ||
|
27bcdc52a0 | ||
|
50cb5b1ece | ||
|
eda8b8b42c | ||
|
62eb86e5ec | ||
|
d7ac074608 | ||
|
c123a04fd7 | ||
|
156a63ea02 | ||
|
97c4aaf20c | ||
|
fc2e4137f5 | ||
|
7ed95d2701 | ||
|
8e13a2190b | ||
|
e1a75e68a1 | ||
|
3240ca7760 | ||
|
31cc8f75c5 | ||
|
74d82f5872 | ||
|
cad7ff2129 | ||
|
1639866515 | ||
|
c735f4dd50 | ||
|
2508d084d0 | ||
|
1bf4583525 | ||
|
e6f7d8a207 | ||
|
4322001225 | ||
|
ae050fdc5b | ||
|
16fcf932ff | ||
|
b8ef4c33da | ||
|
e3900b6f9e | ||
|
5870a3814c | ||
|
333fe16661 | ||
|
3026eed365 | ||
|
f16c7e0b11 | ||
|
eb429506f5 | ||
|
870852b97a | ||
|
ca4c840da4 | ||
|
bf1818da69 | ||
|
0c87981d43 | ||
|
cb9aa77312 | ||
|
e2ffe1ca72 | ||
|
832513c750 | ||
|
6ebbdec414 | ||
|
2dbd0d7764 | ||
|
0a0ff63fec | ||
|
28242e5a2c | ||
|
67c5425b67 | ||
|
a56598888d | ||
|
abbc3b96d2 | ||
|
60cc0d06cb | ||
|
71367cf330 | ||
|
cc6f67dcc0 | ||
|
82f432136e | ||
|
143d6a67cc | ||
|
91fd06b695 | ||
|
8ae7ff5a8c | ||
|
62cd098bdd | ||
|
6a72265a7b | ||
|
3be099bdf8 | ||
|
134ccdaded | ||
|
d9a8baeb93 | ||
|
0381242401 | ||
|
7e66128000 | ||
|
15c1463f5a | ||
|
56aebd69e7 | ||
|
72fadaa866 | ||
|
9277754f5e | ||
|
e15e5703b4 | ||
|
ad7b55704e | ||
|
68a01f94f2 | ||
|
5150fe4651 | ||
|
df44298137 | ||
|
742d89f08a | ||
|
6b16e3d488 |
BIN
src/assets/iscs_picture/bg-door-stand-A.png
Normal file
BIN
src/assets/iscs_picture/bg-door-stand-A.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/iscs_picture/bg-door-station-A.png
Normal file
BIN
src/assets/iscs_picture/bg-door-station-A.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -78,6 +78,8 @@ import bgStationC from '@/assets/iscs_picture/bg-station-C.png'
|
|||||||
import bgStationD from '@/assets/iscs_picture/bg-station-D.png'
|
import bgStationD from '@/assets/iscs_picture/bg-station-D.png'
|
||||||
import bgStationE from '@/assets/iscs_picture/bg-station-E.png'
|
import bgStationE from '@/assets/iscs_picture/bg-station-E.png'
|
||||||
import bgStationF from '@/assets/iscs_picture/bg-station-F.png'
|
import bgStationF from '@/assets/iscs_picture/bg-station-F.png'
|
||||||
|
import bgDoorStationA from '@/assets/iscs_picture/bg-door-station-A.png';
|
||||||
|
import bgDoorStandA from '@/assets/iscs_picture/bg-door-stand-A.png';
|
||||||
|
|
||||||
const pictureObj = {
|
const pictureObj = {
|
||||||
'psdLeft': psdLeft,
|
'psdLeft': psdLeft,
|
||||||
@ -155,7 +157,9 @@ const pictureObj = {
|
|||||||
bgStationC,
|
bgStationC,
|
||||||
bgStationD,
|
bgStationD,
|
||||||
bgStationE,
|
bgStationE,
|
||||||
bgStationF
|
bgStationF,
|
||||||
|
bgDoorStationA,
|
||||||
|
bgDoorStandA
|
||||||
};
|
};
|
||||||
export default class Picture extends Group {
|
export default class Picture extends Group {
|
||||||
constructor(device) {
|
constructor(device) {
|
||||||
|
118
src/iscs_new/animateHandle.js
Normal file
118
src/iscs_new/animateHandle.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import Group from 'zrender/src/container/Group';
|
||||||
|
|
||||||
|
function traverse(group, map) {
|
||||||
|
group.eachChild(el => {
|
||||||
|
if (el instanceof Group) {
|
||||||
|
traverse(el, map);
|
||||||
|
} else {
|
||||||
|
map[el.name] = el;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Animate {
|
||||||
|
constructor(state) {
|
||||||
|
this._state = {...state};
|
||||||
|
this._sum = 0;
|
||||||
|
this._count = 0;
|
||||||
|
this._first = true;
|
||||||
|
this._dispose = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
run(interval) {
|
||||||
|
this._sum = this._sum + interval;
|
||||||
|
const total = this._state.time + (this._first ? this._state.delay : 0);
|
||||||
|
if (this._sum > total) {
|
||||||
|
this.animate(this);
|
||||||
|
this._count = this._count + 1;
|
||||||
|
this._sum = 0;
|
||||||
|
this._first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoop() {
|
||||||
|
return this._state.loop || this._count < this._state.frameList.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
isNeedDefault() {
|
||||||
|
return this._state.needDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDispose() {
|
||||||
|
return this._dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
isEqual(code) {
|
||||||
|
return this._state.code == code;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIndex(index = 0) {
|
||||||
|
return index || this._count % this._state.frameList.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFrame(index = 0) {
|
||||||
|
return this._state.frameList[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
animate() {
|
||||||
|
const shape = this._state.shape;
|
||||||
|
const mapShape = this._state.mapShape;
|
||||||
|
const index = this.getIndex();
|
||||||
|
const frame = this.getFrame(index);
|
||||||
|
if (shape && mapShape && frame) {
|
||||||
|
const mapView = traverse(shape, {});
|
||||||
|
if (this.isNeedDefault()) {
|
||||||
|
Object.keys(mapShape).forEach(name => {
|
||||||
|
const state = mapShape[name];
|
||||||
|
const view = mapView[name];
|
||||||
|
if (view) {
|
||||||
|
shape.setInvisible(shape.model.base.hide);
|
||||||
|
view.attr({shape: state.default.shape, style: state.default.style});
|
||||||
|
view.dirty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(frame).forEach(name => {
|
||||||
|
const view = mapView[name];
|
||||||
|
const model = frame[name];
|
||||||
|
if (view && model) {
|
||||||
|
shape.setInvisible(model.hide);
|
||||||
|
view.attr({shape: model.shape, style: model.style});
|
||||||
|
view.dirty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
this._dispose = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnimateHandle {
|
||||||
|
constructor(painter) {
|
||||||
|
this._animates = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
onframe(delay) {
|
||||||
|
const animate = this._animates.shift();
|
||||||
|
if (animate) {
|
||||||
|
animate.run(delay);
|
||||||
|
if (!animate.isDispose() && animate.isLoop()) {
|
||||||
|
this._animates.push(animate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animate(state) {
|
||||||
|
const animate = this._animates.find(el => el.isEqual(state.code));
|
||||||
|
if (animate) {
|
||||||
|
animate.dispose();
|
||||||
|
}
|
||||||
|
this._animates.push(new Animate(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AnimateHandle;
|
3
src/iscs_new/config/defaultState.js
Normal file
3
src/iscs_new/config/defaultState.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
30
src/iscs_new/config/defaultStyle.js
Normal file
30
src/iscs_new/config/defaultStyle.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const defaultStyle = {
|
||||||
|
/** 透明填充 颜色*/
|
||||||
|
transparentColor : 'transparent',
|
||||||
|
|
||||||
|
/** 默认背景 颜色*/
|
||||||
|
backgroundColor : '#000000',
|
||||||
|
|
||||||
|
/** 默认字体 族类*/
|
||||||
|
fontFamily : 'SimSun,Times New Roman',
|
||||||
|
|
||||||
|
/** 默认字体 大小*/
|
||||||
|
fontSize : 12,
|
||||||
|
|
||||||
|
/** 选中透明度*/
|
||||||
|
opacity : 0.5,
|
||||||
|
|
||||||
|
/** 提亮度*/
|
||||||
|
liftLevel : 0.8,
|
||||||
|
|
||||||
|
/** 边框宽度*/
|
||||||
|
borderWidth : 1,
|
||||||
|
|
||||||
|
/** 边框颜色*/
|
||||||
|
borderColor : '#000',
|
||||||
|
|
||||||
|
/** 边框Dash*/
|
||||||
|
borderDash: [4, 4]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defaultStyle;
|
6
src/iscs_new/constant/shapeEvent.js
Normal file
6
src/iscs_new/constant/shapeEvent.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
ShowBorder: 'showBorder',
|
||||||
|
HideBorder: 'hideBorder',
|
||||||
|
ShowTips: 'showTips',
|
||||||
|
HideTips: 'hideTips'
|
||||||
|
}
|
5
src/iscs_new/constant/shapeLayer.js
Normal file
5
src/iscs_new/constant/shapeLayer.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default {
|
||||||
|
HightLight: `__hightLight__`,
|
||||||
|
Selecting: `___selecting__`,
|
||||||
|
Tips: `__tips__`,
|
||||||
|
}
|
8
src/iscs_new/constant/shapeRender.js
Normal file
8
src/iscs_new/constant/shapeRender.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export default {
|
||||||
|
zlevel: 1,
|
||||||
|
z: 9,
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
origin: [0, 0]
|
||||||
|
}
|
6
src/iscs_new/constant/shapeType.js
Normal file
6
src/iscs_new/constant/shapeType.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const shapeType = {
|
||||||
|
Compose: 'Compose',
|
||||||
|
Element: 'Element'
|
||||||
|
};
|
||||||
|
|
||||||
|
export default shapeType;
|
351
src/iscs_new/controller.js
Normal file
351
src/iscs_new/controller.js
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
import * as eventTool from 'zrender/src/core/event';
|
||||||
|
import Storage from './utils/storage';
|
||||||
|
import Eventful from 'zrender/src/mixin/Eventful';
|
||||||
|
import DragHandle from './dragHandle';
|
||||||
|
import SelectingHandle from './selectingHandle';
|
||||||
|
import SelectHandle from './selectHandle';
|
||||||
|
import KeyBoardHandle from './keyboardHandle';
|
||||||
|
import events from './utils/events';
|
||||||
|
|
||||||
|
class MouseEvent {
|
||||||
|
constructor(controller, e) {
|
||||||
|
const shapeFactory = controller.$map.getShapeFactory();
|
||||||
|
const shape = e.target;
|
||||||
|
this.clientX = e.event.clientX;
|
||||||
|
this.clientY = e.event.clientY;
|
||||||
|
|
||||||
|
if (shape && !['@ignore', '@selecting', '@border', '@drag'].includes(shape.subType)) {
|
||||||
|
if (shape.code) {
|
||||||
|
let composeCode = shape.composeCode;
|
||||||
|
let compose = null;
|
||||||
|
|
||||||
|
while(composeCode) {
|
||||||
|
compose = shapeFactory.getShapeByCode(composeCode);
|
||||||
|
composeCode = compose.model.composeCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.code = compose? compose.code: shape.code;
|
||||||
|
this.type = compose? compose.type: shape.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape.subType) {
|
||||||
|
this.subType = shape.subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape.val) {
|
||||||
|
this.val = shape.val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Controller extends Eventful {
|
||||||
|
constructor(map) {
|
||||||
|
super();
|
||||||
|
this.$map = map;
|
||||||
|
this.option = map.getOption();
|
||||||
|
this.events = map.getEvents();
|
||||||
|
this._pan =false;
|
||||||
|
this._isNotLeftMouse = false;
|
||||||
|
this._shortcuts = '';
|
||||||
|
this._distance = 0;
|
||||||
|
this._target = null;
|
||||||
|
this.initModule(map);
|
||||||
|
this.initHandler(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
initModule(map) {
|
||||||
|
this.dragHandle = new DragHandle(map, this);
|
||||||
|
this.selectingHandle = new SelectingHandle(map, this);
|
||||||
|
this.selectHandle = new SelectHandle(map, this);
|
||||||
|
this.keyBoardHandle = new KeyBoardHandle(map, this);
|
||||||
|
this._storage = new Storage();
|
||||||
|
}
|
||||||
|
|
||||||
|
initHandler(map) {
|
||||||
|
const that = this;
|
||||||
|
const zr = map.getZr();
|
||||||
|
const keyupHandle = this.keyup.bind(this);
|
||||||
|
const keydownHandle = this.keydown.bind(this);
|
||||||
|
|
||||||
|
const dragStartHandle = this.dragHandle.onDragStart;
|
||||||
|
const draggingHandle = this.dragHandle.onDragging;
|
||||||
|
const dragEndHandle = this.dragHandle.onDragEnd;
|
||||||
|
const selectStartHandle = this.selectingHandle.onSelectStart;
|
||||||
|
const selectingHandle = this.selectingHandle.onSelecting;
|
||||||
|
const selectEndHandle = this.selectingHandle.onSelectEnd;
|
||||||
|
const selectedHandle = this.selectHandle.onSelected;
|
||||||
|
const boardKeyupHandle = this.keyBoardHandle.onKeyup;
|
||||||
|
const boardKeydownHandle = this.keyBoardHandle.onKeydown;
|
||||||
|
|
||||||
|
this.on(this.events.__DragStart, dragStartHandle, this.dragHandle); // 单个元素拖拽
|
||||||
|
this.on(this.events.__Dragging, draggingHandle, this.dragHandle);
|
||||||
|
this.on(this.events.__DragEnd, dragEndHandle, this.dragHandle);
|
||||||
|
this.on(this.events.__SelectStart, selectStartHandle, this.selectingHandle);
|
||||||
|
this.on(this.events.__Selecting, selectingHandle, this.selectingHandle);
|
||||||
|
this.on(this.events.__SelectEnd, selectEndHandle, this.selectingHandle);
|
||||||
|
this.on(this.events.__Selected, selectedHandle, this.selectHandle);
|
||||||
|
|
||||||
|
zr.on('click', this.click, this);
|
||||||
|
zr.on('contextmenu', this.contextmenu, this);
|
||||||
|
|
||||||
|
this.enable = function (opts={}) {
|
||||||
|
that._panEnable = opts.panEnable || that._panEnable || false;
|
||||||
|
that._zoomEnable = opts.zoomEnable || that._zoomEnable || false;
|
||||||
|
that._keyEnable = opts.keyEnable || that._keyEnable || false;
|
||||||
|
that._dragEnable = opts.draggle || that._dragEnable || false;
|
||||||
|
that._areaSelectEnable = opts.selecting || that._areaSelectEnable || false;
|
||||||
|
that._selectEnable = opts.selectable || that._selectEnable || false;
|
||||||
|
that._reflectEnable = opts.reflect || that._reflectEnable || false;
|
||||||
|
that._preventDefaultMouseMove = opts.preventDefaultMouseMove || that._preventDefaultMouseMove|| true;
|
||||||
|
that.disable();
|
||||||
|
|
||||||
|
zr.on('mousedown', that.mousedown, that);
|
||||||
|
zr.on('mousemove', that.mousemove, that);
|
||||||
|
zr.on('mouseup', that.mouseup, that);
|
||||||
|
zr.on('globalout', that.mouseup, that);
|
||||||
|
zr.on('mousewheel', that.mousewheel, that);
|
||||||
|
|
||||||
|
zr.dom.addEventListener('keyup', keyupHandle, false);
|
||||||
|
zr.dom.addEventListener('keydown', keydownHandle, false);
|
||||||
|
zr.dom.focus();
|
||||||
|
|
||||||
|
that.on(that.events.__Keyup, boardKeyupHandle, that.keyBoardHandle);
|
||||||
|
that.on(that.events.__Keydown, boardKeydownHandle, that.keyBoardHandle);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.disable = function () {
|
||||||
|
zr.off('mousedown', that.mousedown);
|
||||||
|
zr.off('mousemove', that.mousemove);
|
||||||
|
zr.off('mouseup', that.mouseup);
|
||||||
|
zr.off('globalout', that.mouseup);
|
||||||
|
zr.off('mousewheel', that.mousewheel);
|
||||||
|
|
||||||
|
zr.dom.removeEventListener('keyup', keyupHandle, false);
|
||||||
|
zr.dom.removeEventListener('keydown', keydownHandle, false);
|
||||||
|
|
||||||
|
that.off(that.events.__Keyup, boardKeyupHandle);
|
||||||
|
that.off(that.events.__Keydown, boardKeydownHandle);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dispose = function () {
|
||||||
|
zr.off('click', that.click);
|
||||||
|
zr.off('contextmenu', that.contextmenu);
|
||||||
|
that.off(that.events.__DragStart, dragStartHandle);
|
||||||
|
that.off(that.events.__Dragging, draggingHandle);
|
||||||
|
that.off(that.events.__DragEnd, dragEndHandle);
|
||||||
|
that.off(that.events.__SelectStart, selectStartHandle);
|
||||||
|
that.off(that.events.__Selecting, selectingHandle);
|
||||||
|
that.off(that.events.__SelectEnd, selectEndHandle);
|
||||||
|
that.off(that.events.__Selected, selectedHandle);
|
||||||
|
that.disable();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
isSpecialSubType(e) {
|
||||||
|
return ['@ignore', '@selecting', '@drag', '@border'].includes(e.subType);
|
||||||
|
}
|
||||||
|
|
||||||
|
isSelected(code) {
|
||||||
|
return this._storage.has(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTarget(target) {
|
||||||
|
this._target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCursorStyle(cursorStyle) {
|
||||||
|
this.$map.setCursorStyle(cursorStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
limitDrag(e) {
|
||||||
|
const dx2 = Math.pow(e.dx, 2);
|
||||||
|
const dy2 = Math.pow(e.dy, 2);
|
||||||
|
const scale = this.option.getScaleRate();
|
||||||
|
const diff = Math.ceil(Math.sqrt(dx2+dy2));
|
||||||
|
return (scale > 1) || (diff > 2/scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
mousedown(e) {
|
||||||
|
const event = new MouseEvent(this, e);
|
||||||
|
const zr = this.$map.getZr();
|
||||||
|
|
||||||
|
this._x = e.offsetX;
|
||||||
|
this._y = e.offsetY;
|
||||||
|
this._pan = false;
|
||||||
|
this._target = this.$map.getShapeByCode(event.code);
|
||||||
|
|
||||||
|
zr.dom.focus();
|
||||||
|
this._isNotLeftMouse = eventTool.isMiddleOrRightButtonOnMouseUpDown(e);
|
||||||
|
this.trigger(events.Click, this._target);
|
||||||
|
this.selectingHandle.clear();
|
||||||
|
|
||||||
|
if (this._isNotLeftMouse) {
|
||||||
|
this.setCursorStyle('grab');
|
||||||
|
} else {
|
||||||
|
if (this.isSpecialSubType(event)) { return; }
|
||||||
|
if (this._dragEnable) {
|
||||||
|
this.trigger(this.events.__DragStart, { x: e.offsetX, y: e.offsetY, code: event.code });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._areaSelectEnable) {
|
||||||
|
this.trigger(this.events.__SelectStart, { x: e.offsetX, y: e.offsetY});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mousemove(e) {
|
||||||
|
const oldX = this._x;
|
||||||
|
const oldY = this._y;
|
||||||
|
const target = this._target||{}
|
||||||
|
const dx = Math.round(e.offsetX - this._x);
|
||||||
|
const dy = Math.round(e.offsetY - this._y);
|
||||||
|
|
||||||
|
this._x = e.offsetX;
|
||||||
|
this._y = e.offsetY;
|
||||||
|
this._preventDefaultMouseMove && eventTool.stop(e.event);
|
||||||
|
|
||||||
|
if (this._isNotLeftMouse) {
|
||||||
|
if (this._panEnable) {
|
||||||
|
if (dx**2 + dy**2 > 8) {
|
||||||
|
this._pan = true;
|
||||||
|
}
|
||||||
|
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
|
||||||
|
this.setCursorStyle('grabbing');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this._dragEnable && this.dragHandle.isDragging()) {
|
||||||
|
this.selectingHandle.clear();
|
||||||
|
if (this.limitDrag({dx, dy})) {
|
||||||
|
this.trigger(this.events.__Dragging, { dx, dy });
|
||||||
|
if (this._reflectEnable) {
|
||||||
|
this.trigger(events.Reflect, {dx, dy, code: target.code});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._x = oldX;
|
||||||
|
this._y = oldY;
|
||||||
|
}
|
||||||
|
} else if (this._areaSelectEnable && this.selectingHandle.isSelecting()) {
|
||||||
|
this.trigger(this.events.__Selecting, { x: e.offsetX, y: e.offsetY });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseup(e) {
|
||||||
|
const target = this._target;
|
||||||
|
if (this._isNotLeftMouse) {
|
||||||
|
this._isNotLeftMouse = false;
|
||||||
|
this.setCursorStyle('auto');
|
||||||
|
} else {
|
||||||
|
if (this._selectEnable && target) {
|
||||||
|
this.trigger(this.events.__Selected, { target });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._dragEnable && this.dragHandle.isDragging()) {
|
||||||
|
this.selectingHandle.clear();
|
||||||
|
this.trigger(this.events.__DragEnd, {x: e.offsetX, y: e.offsetY});
|
||||||
|
} else if (this._areaSelectEnable && this.selectingHandle.isSelecting()) {
|
||||||
|
this.trigger(this.events.__SelectEnd, { x: e.offsetX, y: e.offsetY });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mousewheel(e) {
|
||||||
|
const zoomEnable = this._zoomEnable;
|
||||||
|
const wheelDelta = e.wheelDelta;
|
||||||
|
const originX = Math.ceil(e.offsetX);
|
||||||
|
const originY = Math.ceil(e.offsetY);
|
||||||
|
|
||||||
|
if (wheelDelta === 0 || !zoomEnable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoomEnable) {
|
||||||
|
eventTool.stop(e.event);
|
||||||
|
|
||||||
|
let scale = 1;
|
||||||
|
if (wheelDelta > 0) {
|
||||||
|
scale = 1;
|
||||||
|
this.setCursorStyle('zoom-in');
|
||||||
|
} else if (wheelDelta < 0) {
|
||||||
|
scale = -1;
|
||||||
|
this.setCursorStyle('zoom-out');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trigger(this.events.__Zoom, {type: this.events.__Zoom, scale, originX, originY });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
click(e) {
|
||||||
|
const event = new MouseEvent(this, e);
|
||||||
|
if (!event.code) {
|
||||||
|
this.selectHandle.clear();
|
||||||
|
this.selectingHandle.clear();
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextmenu(e) {
|
||||||
|
eventTool.stop(e.event);
|
||||||
|
|
||||||
|
const event = new MouseEvent(this, e);
|
||||||
|
if (!this._pan) {
|
||||||
|
this.trigger(events.ContextMenu, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pan = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
keydown(e) {
|
||||||
|
let shortcuts = e.key;
|
||||||
|
|
||||||
|
if (e.altKey && e.key != 'Alt') {
|
||||||
|
shortcuts = `Alt_${shortcuts}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.shiftKey && e.key != 'Shift') {
|
||||||
|
shortcuts = `Shift_${shortcuts}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.ctrlKey && e.key != 'Control') {
|
||||||
|
shortcuts = `Control_${shortcuts}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._shortcuts = shortcuts;
|
||||||
|
this.trigger(this.events.__Keydown, {key: shortcuts});
|
||||||
|
this.trigger(events.Keydown, {key: shortcuts});
|
||||||
|
}
|
||||||
|
|
||||||
|
keyup(e) {
|
||||||
|
this.trigger(this.events.__Keyup, {key: this._shortcuts});
|
||||||
|
this.trigger(events.Keyup, {key: this._shortcuts})
|
||||||
|
this._shortcuts = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
const shapeFactory = this.$map.getShapeFactory();
|
||||||
|
this._storage.values().forEach(shape => shapeFactory.hideHightLight(shape));
|
||||||
|
this._storage.clear();
|
||||||
|
this._storage.clearClipboard();
|
||||||
|
this._target = null;
|
||||||
|
this._pan = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStorage() {
|
||||||
|
return this._storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeyStr() {
|
||||||
|
return this._shortcuts;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTarget() {
|
||||||
|
return this._target;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy () {
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
100
src/iscs_new/core/abstractShape.js
Normal file
100
src/iscs_new/core/abstractShape.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import * as graphic from '../core/graphic';
|
||||||
|
import * as utils from '../utils/utils';
|
||||||
|
import * as color from 'zrender/src/tool/color';
|
||||||
|
import Group from 'zrender/src/container/Group';
|
||||||
|
import shapeRender from '../constant/shapeRender';
|
||||||
|
import defaultStyle from '../config/defaultStyle';
|
||||||
|
|
||||||
|
function shapeStyleBuilder({subType, model}) {
|
||||||
|
return {
|
||||||
|
subType: subType,
|
||||||
|
...shapeRender,
|
||||||
|
code: model.code,
|
||||||
|
type: model.type,
|
||||||
|
z: 9998,
|
||||||
|
cursor: 'pointer',
|
||||||
|
shape: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
lineWidth: defaultStyle.borderWidth,
|
||||||
|
stroke: color.lift(defaultStyle.borderColor, defaultStyle.liftLevel),
|
||||||
|
fill: `rgba(200,200,200,0.5)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图形抽象层
|
||||||
|
// 继承Group是为了直接获取的到包围框不需要进行坐标变化。
|
||||||
|
class AbstractShape extends Group {
|
||||||
|
constructor({model, shapeType, shapeFactory}) {
|
||||||
|
super({...shapeRender, code: model.code, type: model.type});
|
||||||
|
this.model = model;
|
||||||
|
this.shapeType = shapeType;
|
||||||
|
this.shapeFactory = shapeFactory;
|
||||||
|
this.instanceHightLight = new graphic.Rect(shapeStyleBuilder({subType: '@align', model: this.model}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置高亮
|
||||||
|
active() {}
|
||||||
|
|
||||||
|
// 取消高亮
|
||||||
|
inactive() {}
|
||||||
|
|
||||||
|
// 设置获取焦点
|
||||||
|
focus() {}
|
||||||
|
|
||||||
|
// 设置取消焦点
|
||||||
|
blur() {}
|
||||||
|
|
||||||
|
// 绑定数据
|
||||||
|
combine() {}
|
||||||
|
|
||||||
|
// 解除绑定
|
||||||
|
uncouple() {}
|
||||||
|
|
||||||
|
// 获取依赖图形
|
||||||
|
getDepShapes() {}
|
||||||
|
|
||||||
|
// 设置状态
|
||||||
|
setState(state) {}
|
||||||
|
|
||||||
|
// 拖动
|
||||||
|
drift({dx, dy}) {
|
||||||
|
this.model.base.position[0] = this.model.base.position[0] + dx;
|
||||||
|
this.model.base.position[1] = this.model.base.position[1] + dy;
|
||||||
|
this.instance.scale = this.model.base.scale;
|
||||||
|
this.instance.position = this.model.base.position;
|
||||||
|
this.instance.rotation = this.model.base.rotation*Math.PI/180;
|
||||||
|
this.instance.origin = utils.createOrigin(this.instance);
|
||||||
|
this.instance.transform = utils.createTransform({scale: this.model.base.scale, position: this.model.base.position, rotation: this.model.base.rotation*Math.PI/180});
|
||||||
|
this.setInvisible(this.model.base.hide)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改状态
|
||||||
|
attr(attrs) {
|
||||||
|
this.instance? this.instance.attr(attrs): super.attr(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置显隐
|
||||||
|
setInvisible(hide) {
|
||||||
|
hide ? super.hide() : super.show();
|
||||||
|
super.dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历执行
|
||||||
|
traverse(cb) {
|
||||||
|
this.eachChild(el => {
|
||||||
|
if (el.traverse) {
|
||||||
|
el.traverse(cb, el);
|
||||||
|
} else {
|
||||||
|
cb.call(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AbstractShape;
|
859
src/iscs_new/core/form/elementConst.js
Normal file
859
src/iscs_new/core/form/elementConst.js
Normal file
@ -0,0 +1,859 @@
|
|||||||
|
|
||||||
|
import * as graphic from '../../core/graphic';
|
||||||
|
import form2ShapeStyle from './form2ShapeStyle';
|
||||||
|
import form2TextStyle from './form2TextStyle';
|
||||||
|
import types from './types';
|
||||||
|
const graphicType = Object.fromEntries(Object.keys(graphic).map(type => [type, type]));
|
||||||
|
|
||||||
|
const elementConst = {
|
||||||
|
[graphicType.Line]: {
|
||||||
|
type: graphicType.Line,
|
||||||
|
name:'线段',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'x1',
|
||||||
|
label: '起始点横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入起始点横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'y1',
|
||||||
|
label: '起始点纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入起始点纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 100,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'x2',
|
||||||
|
label: '终止点横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入终止点横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 100,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'y2',
|
||||||
|
label: '终止点纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入终止点纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''}
|
||||||
|
// opts.shape.percent number 1 已显示的百分比,用于绘制动画。
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Text]: {
|
||||||
|
type: graphicType.Text,
|
||||||
|
name:'文字',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2TextStyle
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Rect]: {
|
||||||
|
type: graphicType.Rect,
|
||||||
|
name:'矩形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'x',
|
||||||
|
label: '左上角横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入左上角横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'y',
|
||||||
|
label: '左上角纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入左上角纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'width',
|
||||||
|
label: '宽度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'height',
|
||||||
|
label: '高度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入高度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '圆角矩形半径',
|
||||||
|
type: types.NumberArray,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
length:4,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆角矩形半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [0, 0, 0, 0],
|
||||||
|
description: '用于创建圆角矩形。左上、右上、右下、左下角的半径依次为 r1、 r2、 r3、 r4。[1, 1, 1, 1]'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Circle]: {
|
||||||
|
type: graphicType.Circle,
|
||||||
|
name:'圆形',
|
||||||
|
formList:{
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '半径'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Polygon]: {
|
||||||
|
type: graphicType.Polygon,
|
||||||
|
name:'多边形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'points',
|
||||||
|
label: '坐标集合',
|
||||||
|
type: types.Points,
|
||||||
|
precision: 0, step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入坐标集合', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [[0, 0], [100, 100], [100, 200]],
|
||||||
|
description: '每个元素是一个横纵坐标的数组'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'smooth',
|
||||||
|
label: '圆滑程度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
step: 0.05,
|
||||||
|
precision: 2,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入坐标集合', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '取值范围为 0 到 1 之间的数字,0 表示不圆滑'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// [graphicType.Arrow]: {
|
||||||
|
// type: graphicType.Arrow,
|
||||||
|
// name:'箭头',
|
||||||
|
// formList: {
|
||||||
|
// style: [
|
||||||
|
|
||||||
|
// ],
|
||||||
|
// shape: [
|
||||||
|
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
[graphicType.Polyline]: {
|
||||||
|
type: graphicType.Polyline,
|
||||||
|
name:'多边形折线段',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'points',
|
||||||
|
label: '坐标集合',
|
||||||
|
type: types.Points,
|
||||||
|
precision: 0, step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入坐标集合', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [[0, 0], [100, 100], [100, 200]],
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'smooth',
|
||||||
|
label: '圆滑程度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
step: 0.05,
|
||||||
|
precision: 2,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入坐标集合', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 10,
|
||||||
|
description: '取值范围为 0 到 1 之间的数字,0 表示不圆滑'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Isogon]: {
|
||||||
|
type: graphicType.Isogon,
|
||||||
|
name:'正多边形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape:[
|
||||||
|
{
|
||||||
|
prop: 'x',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'y',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 40,
|
||||||
|
description: '半径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'n',
|
||||||
|
label: '边数',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入边数', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 5,
|
||||||
|
description: '边数'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Ellipse]: {
|
||||||
|
type: graphicType.Ellipse,
|
||||||
|
name:'椭圆',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape:[
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'rx',
|
||||||
|
label: '横向半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入横向半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '横向半径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'ry',
|
||||||
|
label: '纵向半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入纵向半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 30,
|
||||||
|
description: '纵向半径'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Arc]: {
|
||||||
|
type: graphicType.Arc,
|
||||||
|
name:'圆弧',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '半径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'startAngle',
|
||||||
|
label: '起始弧度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入起始弧度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '起始弧度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'endAngle',
|
||||||
|
label: '终止弧度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入终止弧度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 180,
|
||||||
|
description: '终止弧度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'clockwise',
|
||||||
|
label: '顺时针方向',
|
||||||
|
type: types.Boolean,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请选择图形是否不可见', trigger: 'change' }
|
||||||
|
],
|
||||||
|
value: true,
|
||||||
|
description: '顺时针方向。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Sector]: {
|
||||||
|
type: graphicType.Sector,
|
||||||
|
name:'扇形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '半径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r0',
|
||||||
|
label: '内半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入内半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 30,
|
||||||
|
description: '内半径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'startAngle',
|
||||||
|
label: '起始弧度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入起始弧度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '起始弧度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'endAngle',
|
||||||
|
label: '终止弧度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入终止弧度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 180,
|
||||||
|
description: '终止弧度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'clockwise',
|
||||||
|
label: '顺时针方向',
|
||||||
|
type: types.Boolean,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请选择图形是否不可见', trigger: 'change' }
|
||||||
|
],
|
||||||
|
value: true,
|
||||||
|
description: '顺时针方向。'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Heart]: {
|
||||||
|
type: graphicType.Heart,
|
||||||
|
name:'心形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'width',
|
||||||
|
label: '宽度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '宽度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'height',
|
||||||
|
label: '高度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入高度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '高度'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Droplet]: {
|
||||||
|
type: graphicType.Droplet,
|
||||||
|
name:'水滴',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心横坐标'},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '圆心纵坐标'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'width',
|
||||||
|
label: '宽度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '宽度'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'height',
|
||||||
|
label: '高度',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入高度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '高度'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[graphicType.Star]: {
|
||||||
|
type: graphicType.Star,
|
||||||
|
name:'星形',
|
||||||
|
formList: {
|
||||||
|
style: [
|
||||||
|
...form2ShapeStyle,
|
||||||
|
{
|
||||||
|
prop: 'fill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: '填充样式。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shape: [
|
||||||
|
{
|
||||||
|
prop: 'cx',
|
||||||
|
label: '圆心横坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心横坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'cy',
|
||||||
|
label: '圆心纵坐标',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入圆心纵坐标', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'n',
|
||||||
|
label: '瓣数',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入瓣数', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 5,
|
||||||
|
description: '如瓣数等于 5 时,是我们熟悉的五角星。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r',
|
||||||
|
label: '半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 10,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'r0',
|
||||||
|
label: '内半径',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入内半径', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 5,
|
||||||
|
description: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default elementConst;
|
86
src/iscs_new/core/form/form2Base.js
Normal file
86
src/iscs_new/core/form/form2Base.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import types from './types';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
prop: 'z1',
|
||||||
|
label: '层级z1',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
min:0,
|
||||||
|
max:20,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入层级z', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 10,
|
||||||
|
description: '控制图形的前后顺序。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'z2',
|
||||||
|
label: '层级z2',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入层级z2', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 50,
|
||||||
|
description: '控制图形的前后顺序。z2 值小的图形会被 z2 值大的图形覆盖。z2 相比 z1 优先级更低。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'hide',
|
||||||
|
label: '是否隐藏',
|
||||||
|
type: types.Boolean,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请选择图形是否不可见', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: false,
|
||||||
|
description: '图形是否不可见,选中时不绘制图形。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'position',
|
||||||
|
label: '位置',
|
||||||
|
type: types.NumberArray,
|
||||||
|
length:2,
|
||||||
|
precision: 0,
|
||||||
|
min:0,
|
||||||
|
max:20000,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入位置', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [0, 0],
|
||||||
|
description: '控制图形的位置。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'scale',
|
||||||
|
label: '缩放',
|
||||||
|
type: types.NumberArray,
|
||||||
|
length:2,
|
||||||
|
precision: 0,
|
||||||
|
min:0.1,
|
||||||
|
max:1,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入缩放', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [1, 1],
|
||||||
|
description: '控制图形的缩放。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'rotation',
|
||||||
|
label: '旋转',
|
||||||
|
type: types.Number,
|
||||||
|
precision: 0,
|
||||||
|
min:0,
|
||||||
|
max:360,
|
||||||
|
step:1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入旋转', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '控制图形的旋转。'
|
||||||
|
}
|
||||||
|
];
|
120
src/iscs_new/core/form/form2ShapeStyle.js
Normal file
120
src/iscs_new/core/form/form2ShapeStyle.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import types from './types';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
prop: 'lineWidth',
|
||||||
|
label: '线宽',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入线宽', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 1,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'opacity',
|
||||||
|
label: '不透明度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1,
|
||||||
|
step: 0.05,
|
||||||
|
precision: 2,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入不透明度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 1,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'stroke',
|
||||||
|
label: '描边样式',
|
||||||
|
type: types.Color,
|
||||||
|
value: '#000',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'lineDash',
|
||||||
|
label: '描边虚线',
|
||||||
|
type: types.NumberArray,
|
||||||
|
length:2,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
value: [0, 0],
|
||||||
|
description: '描边虚线样式,参考 SVG stroke-dasharray。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'lineDashOffset',
|
||||||
|
label: '描边虚线偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
value: [0, 0],
|
||||||
|
description: '描边虚线偏移,参考 SVG stroke-dashoffset。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'shadowColor',
|
||||||
|
label: '阴影颜色',
|
||||||
|
type: types.Color,
|
||||||
|
value: 'rgba(0,0,0,0)',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'shadowOffsetX',
|
||||||
|
label: '阴影横向偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'shadowOffsetY',
|
||||||
|
label: '阴影纵向偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'shadowBlur',
|
||||||
|
label: '阴影模糊大小',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precision: 0,
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'strokeNoScale',
|
||||||
|
label: '描边不缩放',
|
||||||
|
type: types.Boolean,
|
||||||
|
value: false,
|
||||||
|
description: '不选中时则会根据缩放同比例缩放描边粗细。'
|
||||||
|
// 描边粗细不随缩放而改变,
|
||||||
|
}
|
||||||
|
// {
|
||||||
|
// prop: 'blend',
|
||||||
|
// label: '混合模式',
|
||||||
|
// type: types.String,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入混合模式', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: '',
|
||||||
|
// description: '混合模式,同 Canvas globalCompositeOperation。'
|
||||||
|
// }
|
||||||
|
];
|
416
src/iscs_new/core/form/form2TextStyle.js
Normal file
416
src/iscs_new/core/form/form2TextStyle.js
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
import types from './types';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
prop: 'text',
|
||||||
|
label: '内容',
|
||||||
|
type: types.String,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入内容', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '内容',
|
||||||
|
maxlength:1000,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: 'font',
|
||||||
|
// label: '文字样式',
|
||||||
|
// type: types.String,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字样式', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: '',
|
||||||
|
// description: '文字样式,由 fontSize、 fontFamily、 fontStyle、 fontWeight 组成,建议分别设置这几项而非直接设置 font。'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'fontStyle',
|
||||||
|
// label: '',
|
||||||
|
// type: types.String,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字样式', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 'normal',
|
||||||
|
// description: '同 CSS font-style。'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: 'fontWeight',
|
||||||
|
label: '粗细',
|
||||||
|
type: types.Number,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字粗细', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
min: 300,
|
||||||
|
max: 800,
|
||||||
|
step: 100,
|
||||||
|
precisionFlag: 0,
|
||||||
|
value: 300,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'fontSize',
|
||||||
|
label: '大小',
|
||||||
|
type: types.Number,
|
||||||
|
min: 8,
|
||||||
|
max: 30,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字大小', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 16,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: 'fontFamily',
|
||||||
|
// label: '文字族',
|
||||||
|
// type: types.String,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字族', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: '文字样式',
|
||||||
|
// description: '同 CSS font-family。'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: 'textFill',
|
||||||
|
label: '填充样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字填充样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#000',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textStroke',
|
||||||
|
label: '描边样式',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字描边样式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '#fff',
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textStrokeWidth',
|
||||||
|
label: '描边宽度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字描边宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 2,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: 'textWidth',
|
||||||
|
// label: '文字宽度',
|
||||||
|
// type: types.Number,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字宽度', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字宽度。'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textHeight',
|
||||||
|
// label: '文字高度',
|
||||||
|
// type: types.Number,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字高度', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字高度,仅用于设置背景色时需要设置。'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textLineHeight',
|
||||||
|
// label: '文字行高',
|
||||||
|
// type: types.Number,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字行高', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字行高。'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textPosition',
|
||||||
|
// label: '文字位置',
|
||||||
|
// type: types.Select,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字位置', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: '',
|
||||||
|
// description: "文字位置,可以为 'inside'、 'left'、 'right'、 'top'、 'bottom',或一个二维数组 [x, y] 表示相对形状的位置。"
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textOffset',
|
||||||
|
// label: '文字行高',
|
||||||
|
// type: types.Point,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字位置偏移', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字位置偏移,包括 x、 y。'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: 'textAlign',
|
||||||
|
label: '水平对齐方式',
|
||||||
|
type: types.Select,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字水平对齐方式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'left',
|
||||||
|
optionList:[{value:'left', label:'左对齐'}, {value:'center', label:'居中对齐'}, {value:'right', label:'右对齐'}],
|
||||||
|
// 文字水平对齐方式,可取值:'left'、 'center'、 'right',默认根据 textPosition 计算。
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textVerticalAlign',
|
||||||
|
label: '垂直对齐方式',
|
||||||
|
type: types.Select,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字垂直对齐方式', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'top',
|
||||||
|
optionList:[{value:'top', label:'顶对齐'}, {value:'middle', label:'居中对齐'}, {value:'bottom', label:'底对齐'}],
|
||||||
|
// 文字垂直对齐方式,可取值:'top'、 'middle'、 'bottom',默认根据 textPosition 计算。
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: 'textDistance',
|
||||||
|
// label: '文字与其对齐的边缘的距离',
|
||||||
|
// type: types.Number,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字与其对齐的边缘的距离', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字与其对齐的边缘的距离,如 textPosition 为 top 时,textDistance 表示与形状上方的距离。'
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: 'textShadowColor',
|
||||||
|
label: '阴影颜色',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字阴影颜色', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'rgba(0,0,0,0)',
|
||||||
|
description: '文字阴影颜色。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textShadowBlur',
|
||||||
|
label: '阴影模糊大小',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 10000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字阴影模糊大小', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字阴影模糊大小。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textShadowOffsetX',
|
||||||
|
label: '阴影水平偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字阴影水平偏移', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字阴影水平偏移。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textShadowOffsetY',
|
||||||
|
label: '阴影垂直偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字阴影垂直偏移', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字阴影垂直偏移。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBoxShadowColor',
|
||||||
|
label: '包围盒阴影颜色',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒阴影颜色', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'rgba(0,0,0,0)',
|
||||||
|
description: '文字包围盒阴影颜色。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBoxShadowBlur',
|
||||||
|
label: '包围盒阴影模糊大小',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒阴影模糊大小', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字包围盒阴影模糊大小。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBoxShadowOffsetX',
|
||||||
|
label: '包围盒阴影水平偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒阴影水平偏移', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字包围盒阴影水平偏移。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBoxShadowOffsetY',
|
||||||
|
label: '包围盒阴影垂直偏移',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒阴影垂直偏移。', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字包围盒阴影垂直偏移。'
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: 'transformText',
|
||||||
|
// label: '文字是否跟随变换效果',
|
||||||
|
// type: types.Boolean,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请选择文字是否跟随变换效果', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: false,
|
||||||
|
// description: '文字是否跟随变换效果,仅对 Path 或 Image 元素有效'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textRotation',
|
||||||
|
// label: '文字旋转角度',
|
||||||
|
// type: types.Number,
|
||||||
|
// min: 0,
|
||||||
|
// max: 360,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字旋转角度', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: '文字旋转角度,仅对 Path 或 Image 元素有效,并且 transformText 应设置为 false。'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// prop: 'textOrigin',
|
||||||
|
// label: '文字变换中心',
|
||||||
|
// type: types.Point,
|
||||||
|
// min: 0,
|
||||||
|
// max: 10000,
|
||||||
|
// step: 1,
|
||||||
|
// precisionFlag: 0,
|
||||||
|
// rules:[
|
||||||
|
// { required: true, message:'请输入文字变换中心', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// value: 0,
|
||||||
|
// description: "文字变换中心,可以是 'center' 或一个二维数组 [x, y] 表示相对形状的位置,默认值是 textPosition。"
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
prop: 'textBackgroundColor',
|
||||||
|
label: '包围盒颜色',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒颜色', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'rgba(0,0,0,0)',
|
||||||
|
description: '文字包围盒颜色。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBorderColor',
|
||||||
|
label: '文字包围盒描边颜色',
|
||||||
|
type: types.Color,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒描边颜色', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 'rgba(0,0,0,0)',
|
||||||
|
description: '文字包围盒描边颜色。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBorderWidth',
|
||||||
|
label: '包围盒描边宽度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字包围盒描边宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '文字包围盒描边宽度。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textBorderRadius',
|
||||||
|
label: '圆角大小',
|
||||||
|
type: types.Number,
|
||||||
|
min: 0,
|
||||||
|
max: 360,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字圆角大小', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'textPadding',
|
||||||
|
label: '文字内边距',
|
||||||
|
type: types.NumberArray,
|
||||||
|
length:4,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
step: 1,
|
||||||
|
precisionFlag: 0,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入文字内边距', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: [0, 0, 0, 0],
|
||||||
|
description: '文字内边距,[2, 3, 4, 5] 的形式,单位是像素。'
|
||||||
|
}
|
||||||
|
];
|
49
src/iscs_new/core/form/form2TruncateStyle.js
Normal file
49
src/iscs_new/core/form/form2TruncateStyle.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
export default [
|
||||||
|
{
|
||||||
|
prop: 'outerWidth',
|
||||||
|
label: '外部宽度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 2,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入外部宽度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '包含了 textPadding 的宽度,超出这个范围就裁剪。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'outerHeight',
|
||||||
|
label: '外部高度',
|
||||||
|
type: types.Number,
|
||||||
|
min: 2,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入外部高度', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: 0,
|
||||||
|
description: '包含了 textPadding 的高度,超出这个范围就裁剪。'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'ellipsis',
|
||||||
|
label: '截断超出部分',
|
||||||
|
type: types.String,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入截断超出部分', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '',
|
||||||
|
description: '默认用省略号表示超出部分,也可以对其进行自定义。'
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'placeholder',
|
||||||
|
label: '截断文字',
|
||||||
|
type: types.String,
|
||||||
|
rules:[
|
||||||
|
{ required: true, message:'请输入截断文字', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
value: '',
|
||||||
|
description: '如果空间过小,导致省略号也显示不下,但是又不想空着,可能得有个什么标记表示这里是有字符的,就用个 “点”,就是在这个 placeholder 里设置。'
|
||||||
|
}
|
||||||
|
]
|
40
src/iscs_new/core/form/formBuilder.js
Normal file
40
src/iscs_new/core/form/formBuilder.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import elementConst from './elementConst';
|
||||||
|
import form2Base from './form2Base';
|
||||||
|
|
||||||
|
const formBuilder = {
|
||||||
|
buildForm(el) {
|
||||||
|
const form = {};
|
||||||
|
form.type = el.type;
|
||||||
|
form.name = el.name;
|
||||||
|
form.formGroup = [];
|
||||||
|
form.model = {};
|
||||||
|
|
||||||
|
// 添加通用配置
|
||||||
|
form.model['base'] = {};
|
||||||
|
form2Base.forEach(each=>{
|
||||||
|
form.model['base'][each.prop] = each.value;
|
||||||
|
});
|
||||||
|
form.formGroup.push({name:'通用配置', type:'base', styleList:form2Base});
|
||||||
|
|
||||||
|
const list = [{name:'绘图配置', type:'shape'}, {name:'样式配置', type:'style'}];
|
||||||
|
list.forEach(eachType=>{
|
||||||
|
form.model[eachType.type] = {};
|
||||||
|
const eachList = el.formList[eachType.type];
|
||||||
|
eachList.forEach(each=>{
|
||||||
|
form.model[eachType.type][each.prop] = each.value;
|
||||||
|
});
|
||||||
|
form.formGroup.push({name:eachType.name, type: eachType.type, styleList:eachList});
|
||||||
|
});
|
||||||
|
return form;
|
||||||
|
},
|
||||||
|
buildFormList() {
|
||||||
|
const formList = [];
|
||||||
|
const elementList = Object.values(elementConst);
|
||||||
|
elementList.forEach(el=>{
|
||||||
|
formList.push(this.buildForm(el));
|
||||||
|
});
|
||||||
|
return formList;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default formBuilder;
|
10
src/iscs_new/core/form/types.js
Normal file
10
src/iscs_new/core/form/types.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
String: 'String',
|
||||||
|
Number: 'Number',
|
||||||
|
Select: 'Select',
|
||||||
|
Boolean: 'Boolean',
|
||||||
|
Color: 'Color',
|
||||||
|
Point: 'Point',
|
||||||
|
Points: 'Points',
|
||||||
|
NumberArray: 'NumberArray'
|
||||||
|
};
|
20
src/iscs_new/core/graphic.js
Normal file
20
src/iscs_new/core/graphic.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export {default as Group} from 'zrender/src/container/Group';
|
||||||
|
export {default as Image} from 'zrender/src/graphic/Image';
|
||||||
|
export {default as Text} from 'zrender/src/graphic/Text';
|
||||||
|
export {default as Arc} from './shape/ArcShape';
|
||||||
|
export {default as BezierCurve} from 'zrender/src/graphic/shape/BezierCurve';
|
||||||
|
export {default as Circle} from 'zrender/src/graphic/shape/Circle';
|
||||||
|
export {default as Droplet} from 'zrender/src/graphic/shape/Droplet';
|
||||||
|
export {default as Ellipse} from 'zrender/src/graphic/shape/Ellipse';
|
||||||
|
export {default as Heart} from 'zrender/src/graphic/shape/Heart';
|
||||||
|
export {default as Isogon} from 'zrender/src/graphic/shape/Isogon';
|
||||||
|
export {default as Line} from 'zrender/src/graphic/shape/Line';
|
||||||
|
export {default as Polygon} from 'zrender/src/graphic/shape/Polygon';
|
||||||
|
export {default as Polyline} from 'zrender/src/graphic/shape/Polyline';
|
||||||
|
export {default as Rect} from 'zrender/src/graphic/shape/Rect';
|
||||||
|
export {default as Ring} from 'zrender/src/graphic/shape/Ring';
|
||||||
|
export {default as Rose} from 'zrender/src/graphic/shape/Rose';
|
||||||
|
export {default as Sector} from './shape/SectorShape';
|
||||||
|
export {default as Star} from 'zrender/src/graphic/shape/Star';
|
||||||
|
export {default as Trochoid} from 'zrender/src/graphic/shape/Trochoid';
|
||||||
|
export {default as Svg} from './shape/Svg';
|
17
src/iscs_new/core/shape/ArcShape.js
Normal file
17
src/iscs_new/core/shape/ArcShape.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import Arc from 'zrender/src/graphic/shape/Arc';
|
||||||
|
export default class ArcShape extends Arc {
|
||||||
|
constructor(opts) {
|
||||||
|
opts.shape.startAngle = Math.PI / 180 * opts.shape.startAngle;
|
||||||
|
opts.shape.endAngle = Math.PI / 180 * opts.shape.endAngle;
|
||||||
|
super(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStyle(style) {
|
||||||
|
super.setStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr(key, value) {
|
||||||
|
super.attr(key, value);
|
||||||
|
}
|
||||||
|
}
|
17
src/iscs_new/core/shape/SectorShape.js
Normal file
17
src/iscs_new/core/shape/SectorShape.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import Sector from 'zrender/src/graphic/shape/Sector';
|
||||||
|
export default class ArcShape extends Sector {
|
||||||
|
constructor(opts) {
|
||||||
|
opts.shape.startAngle = Math.PI / 180 * opts.shape.startAngle;
|
||||||
|
opts.shape.endAngle = Math.PI / 180 * opts.shape.endAngle;
|
||||||
|
super(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStyle(style) {
|
||||||
|
super.setStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr(key, value) {
|
||||||
|
super.attr(key, value);
|
||||||
|
}
|
||||||
|
}
|
26
src/iscs_new/core/shape/Svg.js
Normal file
26
src/iscs_new/core/shape/Svg.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
import Path from 'zrender/src/graphic/Path';
|
||||||
|
import * as pathTool from 'zrender/src/tool/path';
|
||||||
|
export default class Svg extends Path {
|
||||||
|
constructor(opts) {
|
||||||
|
super(pathTool.createFromString(opts.shape.path, {
|
||||||
|
...opts,
|
||||||
|
type: 'Svg'
|
||||||
|
}));
|
||||||
|
|
||||||
|
super.attr('position', [opts.shape.x, opts.shape.y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShape(shape) {
|
||||||
|
super.setShape(shape);
|
||||||
|
this.attr('position', [shape.x, shape.y]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStyle(style) {
|
||||||
|
super.setStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr(key, value) {
|
||||||
|
super.attr(key, value);
|
||||||
|
}
|
||||||
|
}
|
45
src/iscs_new/dragHandle.js
Normal file
45
src/iscs_new/dragHandle.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import shapeLayer from './constant/shapeLayer';
|
||||||
|
export default class DragHandle {
|
||||||
|
constructor(map, controller) {
|
||||||
|
this.$zr = map.getZr();
|
||||||
|
this.$controller = controller;
|
||||||
|
this.$option = map.getOption();
|
||||||
|
this.$painter = map.getPainter();
|
||||||
|
this._dragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDragging() {
|
||||||
|
return this._dragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragStart(e) {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
if (e.code && storage.has(e.code)) {
|
||||||
|
this._dragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragging(e) {
|
||||||
|
const dx = e.dx;
|
||||||
|
const dy = e.dy;
|
||||||
|
const scaleRate = this.$option.getScaleRate();
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
|
||||||
|
e.dx = dx / scaleRate;
|
||||||
|
e.dy = dy / scaleRate;
|
||||||
|
|
||||||
|
if (this._dragging) {
|
||||||
|
storage.values().forEach(target => {
|
||||||
|
if (target) {
|
||||||
|
target.shapeFactory.hideHightLight(target);;
|
||||||
|
target.drift(e);
|
||||||
|
target.shapeFactory.showHightLight(target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragEnd(e) {
|
||||||
|
this._dragging = false;
|
||||||
|
}
|
||||||
|
}
|
114
src/iscs_new/factory/compose.js
Normal file
114
src/iscs_new/factory/compose.js
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import * as utils from '../utils/utils';
|
||||||
|
import Group from 'zrender/src/container/Group';
|
||||||
|
import AbstractShape from '../core/abstractShape';
|
||||||
|
import shapeRender from '../constant/shapeRender';
|
||||||
|
import shapeEvent from '../constant/shapeEvent';
|
||||||
|
|
||||||
|
class Compose extends AbstractShape {
|
||||||
|
constructor(args) {
|
||||||
|
super(args);
|
||||||
|
this.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const that = this;
|
||||||
|
// mouse进入事件
|
||||||
|
function onmouseover(e) {
|
||||||
|
that.shapeFactory.trigger(shapeEvent.ShowTips, e, 'text for test');
|
||||||
|
}
|
||||||
|
|
||||||
|
// mouse移动事件
|
||||||
|
function onmousemove(e) {
|
||||||
|
onmouseover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mouse离开事件
|
||||||
|
function onmouseout(e) {
|
||||||
|
that.shapeFactory.trigger(shapeEvent.HideTips, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance = new Group({
|
||||||
|
...shapeRender,
|
||||||
|
...this.model.base,
|
||||||
|
code: this.model.code,
|
||||||
|
type: this.model.type,
|
||||||
|
onmouseover,
|
||||||
|
onmousemove,
|
||||||
|
onmouseout
|
||||||
|
});
|
||||||
|
|
||||||
|
this.model.elementCodes.forEach(code => {
|
||||||
|
const el = this.shapeFactory.getShapeByCode(code);
|
||||||
|
if (el) {
|
||||||
|
this.shapeFactory.removeFromLayer(el.type, el);
|
||||||
|
this.instance.add(el);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.instance.scale = this.model.base.scale;
|
||||||
|
this.instance.position = this.model.base.position;
|
||||||
|
this.instance.rotation = this.model.base.rotation*Math.PI/180;
|
||||||
|
this.instance.origin = utils.createOrigin(this.instance);
|
||||||
|
this.instance.transform = utils.createTransform({scale: this.model.base.scale, position: this.model.base.position, rotation: this.model.base.rotation*Math.PI/180});
|
||||||
|
this.add(this.instance);
|
||||||
|
this.setInvisible(this.model.base.hide)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置高亮
|
||||||
|
active() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消高亮
|
||||||
|
inactive() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置获取焦点
|
||||||
|
focus() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置取消焦点
|
||||||
|
blur() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定数据
|
||||||
|
combine() {
|
||||||
|
this.inactive();
|
||||||
|
this.shapeFactory.hideHightLight(this);
|
||||||
|
this.model.elementCodes.forEach(code => {
|
||||||
|
const el = this.shapeFactory.getShapeByCode(code);
|
||||||
|
if (el && el.model) {
|
||||||
|
this.shapeFactory.hideHightLight(el);
|
||||||
|
this.shapeFactory.removeFromLayer(el.type, el);
|
||||||
|
this.instance.add(el);
|
||||||
|
el.model.composeCode = this.code;
|
||||||
|
el.attr(el.model);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解除绑定
|
||||||
|
uncouple() {
|
||||||
|
this.inactive();
|
||||||
|
this.shapeFactory.hideHightLight(this);
|
||||||
|
this.model.elementCodes.forEach(code => {
|
||||||
|
const el = this.shapeFactory.getShapeByCode(code);
|
||||||
|
if (el && el.model) {
|
||||||
|
this.shapeFactory.hideHightLight(el);
|
||||||
|
this.instance.remove(el);
|
||||||
|
this.shapeFactory.addToLayer(el.type, el);
|
||||||
|
el.model.composeCode = '';
|
||||||
|
el.attr(el.model);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.model.elementCodes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取依赖图形
|
||||||
|
getDepShapes() {
|
||||||
|
return this.model.elementCodes.reduce((shapes, code) => shapes.concat(this.shapeFactory.getShapeByCode(code).getDepShapes()), [this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置状态
|
||||||
|
setState(state) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Compose;
|
118
src/iscs_new/factory/element.js
Normal file
118
src/iscs_new/factory/element.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import * as graphic from '../core/graphic';
|
||||||
|
import * as utils from '../utils/utils';
|
||||||
|
import AbstractShape from '../core/abstractShape';
|
||||||
|
import shapeEvent from '../constant/shapeEvent';
|
||||||
|
import shapeRender from '../constant/shapeRender';
|
||||||
|
import shapeLayer from '../constant/shapeLayer';
|
||||||
|
|
||||||
|
class Element extends AbstractShape {
|
||||||
|
constructor(args) {
|
||||||
|
super(args);
|
||||||
|
this.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const that = this;
|
||||||
|
const elementBuilder = graphic[this.type];
|
||||||
|
if (elementBuilder) {
|
||||||
|
// mouse进入事件
|
||||||
|
function onmouseover(e) {
|
||||||
|
that.shapeFactory.trigger(shapeEvent.ShowTips, e, 'text for test');
|
||||||
|
}
|
||||||
|
|
||||||
|
// mouse移动事件
|
||||||
|
function onmousemove(e) {
|
||||||
|
onmouseover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mouse离开事件
|
||||||
|
function onmouseout(e) {
|
||||||
|
that.shapeFactory.trigger(shapeEvent.HideTips, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance = new elementBuilder({
|
||||||
|
...shapeRender,
|
||||||
|
...this.model.base,
|
||||||
|
code: this.model.code,
|
||||||
|
type: this.model.type,
|
||||||
|
shape: {...this.model.shape},
|
||||||
|
style: {...this.model.style},
|
||||||
|
onmouseover,
|
||||||
|
onmousemove,
|
||||||
|
onmouseout
|
||||||
|
});
|
||||||
|
|
||||||
|
this.instance.scale = this.model.base.scale;
|
||||||
|
this.instance.position = this.model.base.position;
|
||||||
|
this.instance.rotation = this.model.base.rotation*Math.PI/180;
|
||||||
|
this.instance.origin = utils.createOrigin(this.instance);
|
||||||
|
this.instance.transform = utils.createTransform({scale: this.model.base.scale, position: this.model.base.position, rotation: this.model.base.rotation*Math.PI/180});
|
||||||
|
this.add(this.instance);
|
||||||
|
this.setInvisible(this.model.base.hide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置高亮
|
||||||
|
active() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消高亮
|
||||||
|
inactive() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置获取焦点
|
||||||
|
focus() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置取消焦点
|
||||||
|
blur() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定数据
|
||||||
|
combine() {
|
||||||
|
this.inactive();
|
||||||
|
this.shapeFactory.hideHightLight(this);
|
||||||
|
const compose = this.shapeFactory.getShapeByCode(this.model.composeCode);
|
||||||
|
if (compose &&
|
||||||
|
compose.model &&
|
||||||
|
compose.model.elementCodes) {
|
||||||
|
this.shapeFactory.hideHightLight(compose);
|
||||||
|
const index = compose.model.elementCodes.findIndex(this.code);
|
||||||
|
if (index < 0) {
|
||||||
|
compose.model.elementCodes.push(this.code);
|
||||||
|
this.shapeFactory.removeFormLayer(this.type, this);
|
||||||
|
compose.instance.add(this);
|
||||||
|
compose.attr(compose.model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解除绑定
|
||||||
|
uncouple() {
|
||||||
|
this.inactive();
|
||||||
|
this.shapeFactory.hideHightLight(this);
|
||||||
|
const compose = this.shapeFactory.getShapeByCode(this.model.composeCode);
|
||||||
|
if (compose &&
|
||||||
|
compose.model &&
|
||||||
|
compose.model.elementCodes) {
|
||||||
|
this.shapeFactory.hideHightLight(compose);
|
||||||
|
const index = compose.model.elementCodes.findIndex(this.code);
|
||||||
|
if (index >= 0) {
|
||||||
|
compose.model.elementCodes.splice(index, 1);
|
||||||
|
compose.instance.remove(this);
|
||||||
|
compose.attr(compose.model);
|
||||||
|
this.shapeFactory.addToLayer(this.type, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取依赖图形
|
||||||
|
getDepShapes() {
|
||||||
|
return [this];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置状态
|
||||||
|
setState(state) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Element;
|
267
src/iscs_new/factory/index.js
Normal file
267
src/iscs_new/factory/index.js
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
import * as zrUtil from 'zrender/src/core/util';
|
||||||
|
import * as graphic from '../core/graphic';
|
||||||
|
import Eventful from 'zrender/src/mixin/Eventful';
|
||||||
|
import TipsHandle from './tipsHandle';
|
||||||
|
import Compose from './compose';
|
||||||
|
import Element from './element';
|
||||||
|
import shapeType from '../constant/shapeType';
|
||||||
|
import shapeRender from '../constant/shapeRender';
|
||||||
|
import shapeEvent from '../constant/shapeEvent';
|
||||||
|
import orders from '../utils/orders';
|
||||||
|
import shapeLayer from '../constant/shapeLayer';
|
||||||
|
import templateParser from './templateParser';
|
||||||
|
import defaultStyle from '../config/defaultStyle';
|
||||||
|
|
||||||
|
const None = e => null;
|
||||||
|
const shapeBuilderMap = {
|
||||||
|
[shapeType.Element]: Element,
|
||||||
|
[shapeType.Compose]: Compose
|
||||||
|
}
|
||||||
|
const shapeSensitizeStyle = {
|
||||||
|
border: {
|
||||||
|
borderStyle: {
|
||||||
|
lineDash: [4, 4],
|
||||||
|
lineWidth: 1,
|
||||||
|
stroke: '#000',
|
||||||
|
fill: 'transparent'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Perspective extends graphic.Group {
|
||||||
|
constructor(args) {
|
||||||
|
super(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createBorder(rect) {
|
||||||
|
this._border = new graphic.Rect({
|
||||||
|
...shapeRender,
|
||||||
|
subType: '@border',
|
||||||
|
z: 9999,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
...rect
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...shapeSensitizeStyle.border.borderStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.add(this._border);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createAngles() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render(rect) {
|
||||||
|
this.removeAll();
|
||||||
|
this._createBorder(rect);
|
||||||
|
this._createAngles();
|
||||||
|
}
|
||||||
|
|
||||||
|
setShape(rect) {
|
||||||
|
this.render(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ShapeFactory extends Eventful {
|
||||||
|
constructor(map) {
|
||||||
|
super();
|
||||||
|
this.$map = map;
|
||||||
|
this.$painter = map.getPainter();
|
||||||
|
this.$controller = map.getController();
|
||||||
|
|
||||||
|
this.sensitize = new Perspective({subType: '@ignore'});
|
||||||
|
|
||||||
|
this.tipsHandle = new TipsHandle(map);
|
||||||
|
|
||||||
|
this.source = {};
|
||||||
|
this.mapTemplate = {};
|
||||||
|
this.mapShape = {};
|
||||||
|
|
||||||
|
this.initEventHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
initEventHandle() {
|
||||||
|
const that = this;
|
||||||
|
const showBorderHandle = this.showBorder;
|
||||||
|
const hideBorderHandle = this.hideBorder;
|
||||||
|
const showTipsHandle = this.tipsHandle.onShow;
|
||||||
|
const hideTipsHandle = this.tipsHandle.onHide;
|
||||||
|
|
||||||
|
this.on(shapeEvent.ShowBorder, showBorderHandle, this);
|
||||||
|
this.on(shapeEvent.HideBorder, hideBorderHandle, this);
|
||||||
|
this.on(shapeEvent.ShowTips, showTipsHandle, this.tipsHandle);
|
||||||
|
this.on(shapeEvent.HideTips, hideTipsHandle, this.tipsHandle);
|
||||||
|
|
||||||
|
this.dispose = function() {
|
||||||
|
that.off(shapeEvent.ShowBorder, showBorderHandle);
|
||||||
|
that.off(shapeEvent.HideBorder, showBorderHandle);
|
||||||
|
that.off(shapeEvent.ShowTips, showTipsHandle);
|
||||||
|
that.off(shapeEvent.HideTips, hideTipsHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseTemplates(list=[]) {
|
||||||
|
list.forEach(el => {
|
||||||
|
this.mapTemplate[el.type] = templateParser.parse(el);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(source={}, take=None) {
|
||||||
|
try {
|
||||||
|
this.source = source;
|
||||||
|
zrUtil.each(source.elementList ||[], model => {
|
||||||
|
take(this.addShape(this.createShape(model, shapeType.Element)));
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
zrUtil.each(source.composeList ||[], model => {
|
||||||
|
take(this.addShape(this.createShape(model, shapeType.Compose)));
|
||||||
|
}, this);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ERROR] ', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createShape(model={}, shapeType) {
|
||||||
|
let shape = null;
|
||||||
|
const shapeBuilder = shapeBuilderMap[shapeType];
|
||||||
|
if (shapeBuilder) {
|
||||||
|
shape = new shapeBuilder({model, shapeType, shapeFactory: this});
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
addShape(shape) {
|
||||||
|
if (shape && shape.code) {
|
||||||
|
this.mapShape[shape.code] = shape;
|
||||||
|
shape.combine();
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeShape(shape) {
|
||||||
|
if (shape && shape.code) {
|
||||||
|
shape.uncouple();
|
||||||
|
delete this.mapShape[shape.code];
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSource(model={}, action={}) {
|
||||||
|
switch (action.shapeType) {
|
||||||
|
case shapeType.Compose: return update2List(this.source, model, action, 'composeList');
|
||||||
|
case shapeType.Element: return update2List(this.source, model, action, 'elementList');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
showHightLight(shape) {
|
||||||
|
const target = this.$controller.getTarget();
|
||||||
|
|
||||||
|
if (shape.instanceHightLight) {
|
||||||
|
shape.instanceHightLight.setShape(shape.getBoundingRect())
|
||||||
|
this.$painter.addToLayer(shapeLayer.HightLight, shape.instanceHightLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == shape) {
|
||||||
|
this.showBorder(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape.traverse(el => {
|
||||||
|
el.attr({ z: shapeRender.z + 9 })
|
||||||
|
});
|
||||||
|
|
||||||
|
shape.active();
|
||||||
|
}
|
||||||
|
|
||||||
|
hideHightLight(shape) {
|
||||||
|
const target = this.$controller.getTarget();
|
||||||
|
|
||||||
|
if (shape.instanceHightLight) {
|
||||||
|
this.$painter.removeFromLayer(shapeLayer.HightLight, shape.instanceHightLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != shape) {
|
||||||
|
this.hideBorder(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape.traverse(el => {
|
||||||
|
el.attr({ z: shapeRender.z })
|
||||||
|
});
|
||||||
|
|
||||||
|
shape.inactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
showBorder(shape) {
|
||||||
|
this.sensitize.setShape(shape.getBoundingRect());
|
||||||
|
this.$painter.addToLayer(shapeLayer.HightLight, this.sensitize);
|
||||||
|
}
|
||||||
|
|
||||||
|
hideBorder(shape) {
|
||||||
|
this.$painter.removeFromLayer(shapeLayer.HightLight, this.sensitize);
|
||||||
|
}
|
||||||
|
|
||||||
|
addToLayer(level, shape) {
|
||||||
|
return this.$painter.addToLayer(level, shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromLayer(level, shape) {
|
||||||
|
return this.$painter.removeFromLayer(level, shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
isDrawing() {
|
||||||
|
this.$map.isDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
getSource() {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMapTemplate() {
|
||||||
|
return this.mapTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMapShape() {
|
||||||
|
return this.mapShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
getShapeByCode(code) {
|
||||||
|
return this.mapShape[code];
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.source = {};
|
||||||
|
this.mapTemplate = {};
|
||||||
|
this.mapShape = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.clear();
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update2List(source, model, action, name='') {
|
||||||
|
const list = source[name];
|
||||||
|
|
||||||
|
if (!list) { source[name] = []; }
|
||||||
|
|
||||||
|
let updateModel = model;
|
||||||
|
const i = list.findIndex(elem => { return elem.code == model.code; })
|
||||||
|
switch(action.order) {
|
||||||
|
case orders.Binding:
|
||||||
|
case orders.Add:
|
||||||
|
i < 0 && list.push(model);
|
||||||
|
break;
|
||||||
|
case orders.Unbinding:
|
||||||
|
case orders.Delete:
|
||||||
|
i >= 0 && list.splice(i, 1);
|
||||||
|
break;
|
||||||
|
case orders.Update:
|
||||||
|
updateModel = Object.assign(list[i]||{}, model)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShapeFactory;
|
45
src/iscs_new/factory/templateParser.js
Normal file
45
src/iscs_new/factory/templateParser.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import * as utils from '../utils/utils';
|
||||||
|
|
||||||
|
class TemplateParser {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(template) {
|
||||||
|
return {
|
||||||
|
type: template.type,
|
||||||
|
name: template.name,
|
||||||
|
isActive: template.isActive,
|
||||||
|
isFocus: template.isFocus,
|
||||||
|
mapShape: this.parseShape(template.shapeList),
|
||||||
|
mapState: this.parseState(template.stateList),
|
||||||
|
mapEvent: this.parseEvent(template.eventList),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseShape(list=[], map={}) {
|
||||||
|
list.forEach(el => {
|
||||||
|
const mapShape = map[el.name] = {};
|
||||||
|
mapShape[utils.defStatus] = { status: utils.defStatus, style: el.style, shape: el.shape };
|
||||||
|
(el.stateList||[]).forEach(it => {
|
||||||
|
mapShape[it.status] = it;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseState(list=[], map={}) {
|
||||||
|
list.forEach(el => {
|
||||||
|
map[el.status] = el;
|
||||||
|
})
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseEvent(list=[], map={}) {
|
||||||
|
list.forEach(el => {
|
||||||
|
map[el.status] = el;
|
||||||
|
})
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new TemplateParser();
|
55
src/iscs_new/factory/tipsHandle.js
Normal file
55
src/iscs_new/factory/tipsHandle.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import * as graphic from '../core/graphic';
|
||||||
|
import shapeLayer from '../constant/shapeLayer';
|
||||||
|
import shapeRender from '../constant/shapeRender';
|
||||||
|
|
||||||
|
function shapeStyleBuilder() {
|
||||||
|
return {
|
||||||
|
...shapeRender,
|
||||||
|
z: 10000,
|
||||||
|
silent: true,
|
||||||
|
style: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
textBackgroundColor: '#feffc8',
|
||||||
|
text: '',
|
||||||
|
textFill: '#000',
|
||||||
|
textPadding: [7, 14],
|
||||||
|
textAlign: 'left',
|
||||||
|
textVerticalAlign: 'bottom',
|
||||||
|
textBorderColor: '#666666',
|
||||||
|
textBorderWidth: 0,
|
||||||
|
textBorderRadius: 4,
|
||||||
|
textLineHeight: 22,
|
||||||
|
textBoxShadowColor: 'rgba(0,0,0,.3)',
|
||||||
|
textBoxShadowOffsetX: 0,
|
||||||
|
textBoxShadowOffsetY: 1,
|
||||||
|
textBoxShadowBlur: 3,
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default class TipsHandle {
|
||||||
|
constructor(map) {
|
||||||
|
this.$map = map;
|
||||||
|
this.message = new graphic.Text(shapeStyleBuilder());
|
||||||
|
}
|
||||||
|
|
||||||
|
onShow(e, text) {
|
||||||
|
const {offsetX, offsetY} = e;
|
||||||
|
const painter = this.$map.getPainter();
|
||||||
|
const option = this.$map.getOption();
|
||||||
|
const x = (offsetX + option.offsetX) / option.scaleRate;
|
||||||
|
const y = (offsetY + option.offsetY) / option.scaleRate;
|
||||||
|
this.message.setStyle({ x, y, text });
|
||||||
|
painter.addToLayer(shapeLayer.Tips, this.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
onHide(e) {
|
||||||
|
const painter = this.$map.getPainter();
|
||||||
|
|
||||||
|
painter.removeFromLayer(shapeLayer.Tips, this.message);
|
||||||
|
this.message.setStyle('text', '');
|
||||||
|
}
|
||||||
|
}
|
32
src/iscs_new/keyboardHandle.js
Normal file
32
src/iscs_new/keyboardHandle.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
export default class KeyBoardHandle {
|
||||||
|
constructor(map, controller) {
|
||||||
|
this.$map = map;
|
||||||
|
this.$controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
execFunc(moduleName, funcName, args) {
|
||||||
|
const module = this.$controller[moduleName]||{};
|
||||||
|
const func = module[funcName];
|
||||||
|
if (func instanceof Function) {
|
||||||
|
func.apply(module, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeydown(e) {
|
||||||
|
switch (e.key) {
|
||||||
|
case 'v':
|
||||||
|
this.execFunc('selectHandle', 'setDraggable', ['vertical']);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
this.execFunc('selectHandle', 'setDraggable', ['horizontal']);
|
||||||
|
break;
|
||||||
|
case 'Escape':
|
||||||
|
this.execFunc('selectHandle', 'setDraggable', [true]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyup(e) {
|
||||||
|
}
|
||||||
|
}
|
414
src/iscs_new/map.js
Normal file
414
src/iscs_new/map.js
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import * as utils from './utils/utils';
|
||||||
|
import zrender from 'zrender';
|
||||||
|
import events from './utils/events';
|
||||||
|
import Eventful from 'zrender/src/mixin/Eventful';
|
||||||
|
import Painter from './painter';
|
||||||
|
import Option from './option';
|
||||||
|
import Controller from './controller';
|
||||||
|
import StateHandle from './stateHandle';
|
||||||
|
import ShapeFactory from './factory';
|
||||||
|
import orders from './utils/orders';
|
||||||
|
import shapeType from './constant/shapeType';
|
||||||
|
|
||||||
|
const renderer = 'canvas';
|
||||||
|
const devicePixelRatio = 1;
|
||||||
|
class JMap {
|
||||||
|
constructor(opts) {
|
||||||
|
// 内部鼠标事件
|
||||||
|
this.events = {
|
||||||
|
__Pan: '__pan__',
|
||||||
|
__Zoom: '__zoom__',
|
||||||
|
__DragStart: '__dragStart__',
|
||||||
|
__Dragging: '__dragging__',
|
||||||
|
__DragEnd: '__dragEnd__',
|
||||||
|
__SelectStart: '__selectStart__',
|
||||||
|
__Selecting: '__selecting__',
|
||||||
|
__SelectEnd: '__selectEnd__',
|
||||||
|
__Selected: '__selected__',
|
||||||
|
__Keyup: '__keyup__',
|
||||||
|
__Keydown: '__keydown__'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化Map实例
|
||||||
|
this.initMapInstance(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化属性有鼠标事件 缩放等
|
||||||
|
initMapInstance(opts) {
|
||||||
|
const width = opts.dom.clientWidth;
|
||||||
|
const height = opts.dom.clientHeight;
|
||||||
|
const optionHandler = this.setOption.bind(this);
|
||||||
|
|
||||||
|
this.draw = opts.draw;
|
||||||
|
// 实例化zr
|
||||||
|
this.$zr = zrender.init(opts.dom, { renderer, devicePixelRatio, width, height, ...utils.deepClone(opts.config || {})});
|
||||||
|
this.$zr.dom.setAttribute('tabIndex', -1);
|
||||||
|
this.$zr.dom.style.cursor = 'auto';
|
||||||
|
|
||||||
|
// 实例化缩放偏移缩放参数
|
||||||
|
this.$option = new Option({ scaleRate: 1, offsetX: 0, offsetY: 0, ...utils.deepClone(opts.option || {})}, (dataZoom) => { this.$controller.trigger(events.DataZoom, dataZoom); }); // 缩放
|
||||||
|
|
||||||
|
// 实例化绘图模块
|
||||||
|
this.$painter = new Painter(this);
|
||||||
|
this.$painter.updateZrSize({width: this.$zr.getWidth(), height: this.$zr.getHeight()});
|
||||||
|
this.$painter.updateTransform(this.$option);
|
||||||
|
|
||||||
|
// 实例化事件分发模块
|
||||||
|
this.$controller = new Controller(this);
|
||||||
|
this.$controller.enable();
|
||||||
|
this.$controller.on(this.events.__Pan, optionHandler);
|
||||||
|
this.$controller.on(this.events.__Zoom, optionHandler);
|
||||||
|
|
||||||
|
// 名声周期发射器
|
||||||
|
this.$eventEmitter = new Eventful({});
|
||||||
|
|
||||||
|
// 数据容器工厂
|
||||||
|
this.$shapeFactory = new ShapeFactory(this);
|
||||||
|
|
||||||
|
// 状态处理器
|
||||||
|
this.$stateHandle = new StateHandle(this);
|
||||||
|
|
||||||
|
this.disable = function() {
|
||||||
|
this.off(this.events.Pan, optionHandler);
|
||||||
|
this.off(this.events.Zoom, optionHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载插件
|
||||||
|
this.plugins = opts.plugins || [];
|
||||||
|
this.plugins.forEach(el => { this.use(el); });
|
||||||
|
}
|
||||||
|
|
||||||
|
setMap(templates = [], source = {}, eventOpts = {}) {
|
||||||
|
// 清楚数据
|
||||||
|
this.$shapeFactory.clear();
|
||||||
|
this.$painter.clear();
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
this.$controller.enable(eventOpts);
|
||||||
|
|
||||||
|
// 更新视图位置
|
||||||
|
this.$painter.updateTransform(this.$option);
|
||||||
|
|
||||||
|
// 解析模板
|
||||||
|
this.$shapeFactory.parseTemplates(templates);
|
||||||
|
|
||||||
|
// 数据加载完成 回调
|
||||||
|
this.$eventEmitter.trigger(events.DataLoaded);
|
||||||
|
|
||||||
|
// 初次渲染视图
|
||||||
|
this.repaint(source);
|
||||||
|
|
||||||
|
// 设置默认状态
|
||||||
|
this.setDefaultState();
|
||||||
|
|
||||||
|
// 视图加载完成 回调
|
||||||
|
this.$eventEmitter.trigger(events.ViewLoaded);
|
||||||
|
|
||||||
|
// 返回视图缩放偏移
|
||||||
|
this.$option.notice(this.$option);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultState() {
|
||||||
|
this.$eventEmitter.trigger(events.StateLoaded);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOption(opts = {}) {
|
||||||
|
this.$option.update(opts.type == this.events.__Zoom ? pullBack(this.$zr, this.$option, opts) : opts);
|
||||||
|
this.$painter.updateTransform(this.$option);
|
||||||
|
|
||||||
|
this.$controller.disable();
|
||||||
|
this.$controller.enable();
|
||||||
|
|
||||||
|
this.$eventEmitter.trigger(events.OptionUpdate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCenter(code) {
|
||||||
|
const shape = this.$shapeFactory.getShapeByCode(code);
|
||||||
|
if (shape && shape) {
|
||||||
|
var rect = utils.createBoundingRect(shape);
|
||||||
|
var center = utils.calculateDCenter(rect, { width: this.$zr.getWidth(), height: this.$zr.getHeight() });
|
||||||
|
this.setOption(center);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setBackgroundColor(color) {
|
||||||
|
this.$zr.setBackgroundColor(color);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCursorStyle(cursorStyle = 'auto') {
|
||||||
|
this.$zr.setCursorStyle(cursorStyle);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
repaint(source = {}) {
|
||||||
|
this.$shapeFactory.parse(source, shape => {
|
||||||
|
if (shape) {
|
||||||
|
this.$painter.add(shape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(list = []) {
|
||||||
|
list.forEach(({model, action}) => {
|
||||||
|
let updateModel = this.isDrawing() ? this.$shapeFactory.updateSource(model, action) : model;
|
||||||
|
let curShape = this.$shapeFactory.getShapeByCode(updateModel.code);
|
||||||
|
let deps = null;
|
||||||
|
let oldShape = null;
|
||||||
|
let newShape = null;
|
||||||
|
|
||||||
|
if (updateModel) {
|
||||||
|
this.$controller.clear();
|
||||||
|
switch (action.order) {
|
||||||
|
case orders.Binding:
|
||||||
|
case orders.Add:
|
||||||
|
newShape = this.$shapeFactory.createShape(updateModel, action.shapeType);
|
||||||
|
this.$shapeFactory.addShape(newShape);
|
||||||
|
this.$painter.add(newShape);
|
||||||
|
break;
|
||||||
|
case orders.Delete:
|
||||||
|
deps = curShape.getDepShapes();
|
||||||
|
deps.forEach(el => {
|
||||||
|
updateModel = this.isDrawing() ? this.$shapeFactory.updateSource(el, {...action, shapeType: el.shapeType}) : el;
|
||||||
|
if (updateModel) {
|
||||||
|
curShape = this.$shapeFactory.getShapeByCode(updateModel.code);
|
||||||
|
oldShape = this.$shapeFactory.removeShape(curShape);
|
||||||
|
this.$painter.remove(oldShape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case orders.Update:
|
||||||
|
oldShape = this.$shapeFactory.removeShape(curShape);
|
||||||
|
this.$painter.remove(oldShape);
|
||||||
|
newShape = this.$shapeFactory.createShape(updateModel, action.shapeType);
|
||||||
|
this.$shapeFactory.addShape(newShape);
|
||||||
|
this.$painter.add(newShape);
|
||||||
|
break;
|
||||||
|
case orders.Unbinding:
|
||||||
|
oldShape = this.$shapeFactory.removeShape(curShape);
|
||||||
|
this.$painter.remove(oldShape);
|
||||||
|
this.$shapeFactory.addShape(oldShape);
|
||||||
|
this.$painter.add(oldShape);
|
||||||
|
break;
|
||||||
|
// case orders.changeStatus:
|
||||||
|
// // model
|
||||||
|
// this.$painter.update(this.$stateHandle.update(this.$shapeFactory, []));
|
||||||
|
// debugger;
|
||||||
|
// break;
|
||||||
|
// case orders.ResetStatus:
|
||||||
|
// debugger;
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$eventEmitter.trigger(events.ViewUpdate, list);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(list = []) {
|
||||||
|
this.$painter.update(this.$stateHandle.update(this.$shapeFactory, list));
|
||||||
|
this.$eventEmitter.trigger(events.StateUpdate, list);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEvents() {
|
||||||
|
return this.events;
|
||||||
|
}
|
||||||
|
|
||||||
|
getZr() {
|
||||||
|
return this.$zr;
|
||||||
|
}
|
||||||
|
|
||||||
|
getOption() {
|
||||||
|
return this.$option;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPainter() {
|
||||||
|
return this.$painter;
|
||||||
|
}
|
||||||
|
|
||||||
|
getController() {
|
||||||
|
return this.$controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
getStorage() {
|
||||||
|
return this.$controller.getStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
getShapeFactory() {
|
||||||
|
return this.$shapeFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
getShapeByCode(code) {
|
||||||
|
return this.$shapeFactory.getShapeByCode(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSource() {
|
||||||
|
return this.$shapeFactory.getSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
getMapShape() {
|
||||||
|
return this.$shapeFactory.getMapShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
getMapTemplate() {
|
||||||
|
return this.$shapeFactory.getMapTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(opt) {
|
||||||
|
this.$zr.resize(opt);
|
||||||
|
this.$painter.updateZrSize(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
this.$painter.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
isDrawing() {
|
||||||
|
return this.draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.$shapeFactory.clear();
|
||||||
|
this.$controller.clear();
|
||||||
|
this.$painter.clear();
|
||||||
|
this.$zr.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
use(el) {
|
||||||
|
this.plugins.includes(el) || this.plugins.push(el);
|
||||||
|
el.install(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.disable();
|
||||||
|
this.clear();
|
||||||
|
this.$shapeFactory.destroy();
|
||||||
|
this.$controller.destroy();
|
||||||
|
this.$painter.destroy();
|
||||||
|
this.$zr && this.$zr.dispose();
|
||||||
|
this.plugins.forEach(el => {
|
||||||
|
el.uninstall(this);
|
||||||
|
});
|
||||||
|
this.plugins = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
on(name, cb, context) {
|
||||||
|
const idx = Object.values(events).indexOf(name);
|
||||||
|
if (idx >= 0) {
|
||||||
|
switch (name) {
|
||||||
|
case events.DataLoaded:
|
||||||
|
this.$eventEmitter.on(events.DataLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.ViewLoaded:
|
||||||
|
this.$eventEmitter.on(events.ViewLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.StateLoaded:
|
||||||
|
this.$eventEmitter.on(events.StateLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.ViewUpdate:
|
||||||
|
this.$eventEmitter.on(events.ViewUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
case events.StateUpdate:
|
||||||
|
this.$eventEmitter.on(events.StateUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
case events.OptionUpdate:
|
||||||
|
this.$eventEmitter.on(events.OptionUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case events.Click:
|
||||||
|
this.$controller.on(events.Click, cb, context);
|
||||||
|
break;
|
||||||
|
case events.ContextMenu:
|
||||||
|
this.$controller.on(events.ContextMenu, cb, context);
|
||||||
|
break;
|
||||||
|
case events.Reflect:
|
||||||
|
this.$controller.on(events.Reflect, _.throttle(cb, 200), context);
|
||||||
|
break;
|
||||||
|
case events.DataZoom:
|
||||||
|
this.$controller.on(events.DataZoom, cb, context);
|
||||||
|
break;
|
||||||
|
case events.Keydown:
|
||||||
|
this.$controller.on(events.Keydown, cb, context);
|
||||||
|
break;
|
||||||
|
case events.Keypress:
|
||||||
|
this.$controller.on(events.Keypress, cb, context);
|
||||||
|
break;
|
||||||
|
case events.Keyup:
|
||||||
|
this.$controller.on(events.Keyup, cb, context);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
off(name, cb) {
|
||||||
|
const idx = Object.values(events).indexOf(name);
|
||||||
|
if (idx >= 0) {
|
||||||
|
switch (name) {
|
||||||
|
case events.DataLoaded:
|
||||||
|
this.$eventEmitter.off(events.DataLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.ViewLoaded:
|
||||||
|
this.$eventEmitter.off(events.ViewLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.StateLoaded:
|
||||||
|
this.$eventEmitter.off(events.StateLoaded, cb, context);
|
||||||
|
break;
|
||||||
|
case events.ViewUpdate:
|
||||||
|
this.$eventEmitter.off(events.ViewUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
case events.StateUpdate:
|
||||||
|
this.$eventEmitter.off(events.StateUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
case events.OptionUpdate:
|
||||||
|
this.$eventEmitter.off(events.OptionUpdate, cb, context);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case events.Click:
|
||||||
|
this.$controller.off(events.Click, cb);
|
||||||
|
break;
|
||||||
|
case events.ContextMenu:
|
||||||
|
this.$controller.off(events.ContextMenu, cb);
|
||||||
|
break;
|
||||||
|
case events.Reflect:
|
||||||
|
this.$controller.off(events.Reflect, _.throttle(cb, 200));
|
||||||
|
break;
|
||||||
|
case events.DataZoom:
|
||||||
|
this.$controller.off(events.DataZoom, cb);
|
||||||
|
break;
|
||||||
|
case events.Keydown:
|
||||||
|
this.$controller.off(events.Keydown, cb);
|
||||||
|
break;
|
||||||
|
case events.Keypress:
|
||||||
|
this.$controller.off(events.Keypress, cb);
|
||||||
|
break;
|
||||||
|
case events.Keyup:
|
||||||
|
this.$controller.off(events.Keyup, cb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pullBack(zr, option = {}, payload = {}) {
|
||||||
|
const zrWidth = zr.getWidth();
|
||||||
|
const zrHeight = zr.getHeight();
|
||||||
|
const originX = payload.originX || zrWidth / 2;
|
||||||
|
const originY = payload.originY || zrHeight / 2;
|
||||||
|
const x = (option.offsetX + originX) / option.scaleRate;
|
||||||
|
const y = (option.offsetY + originY) / option.scaleRate;
|
||||||
|
const newScaleRate = option.getScaleRate(payload.scale);
|
||||||
|
const dx = originX - (x * newScaleRate - option.offsetX);
|
||||||
|
const dy = originY - (y * newScaleRate - option.offsetY);
|
||||||
|
return {...payload, dx, dy};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JMap;
|
84
src/iscs_new/maps.js
Normal file
84
src/iscs_new/maps.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import * as utils from './utils/utils';
|
||||||
|
import * as Dom from './utils/dom';
|
||||||
|
import JMap from './map';
|
||||||
|
|
||||||
|
const DOM_ATTRIBUTE_KEY = '_maps_instance_';
|
||||||
|
class JMaps {
|
||||||
|
constructor() {
|
||||||
|
this._version = '1.0.0';
|
||||||
|
this.instances = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
init(opts) {
|
||||||
|
if (!opts) {
|
||||||
|
throw new Error('Initialize failed: invalid params.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opts.dom && opts.el) {
|
||||||
|
opts['dom'] = document.getElementById(opts.el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opts.dom) {
|
||||||
|
throw new Error('Initialize failed: invalid dom and el.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const existInstance = this.getInstanceByDom(opts.dom);
|
||||||
|
if (existInstance) {
|
||||||
|
console.warn('There is a chart instance already initialized on the dom.');
|
||||||
|
return existInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dom.isDom(opts.dom) && opts.dom.nodeName.toUpperCase() !== 'CANVAS' &&
|
||||||
|
(
|
||||||
|
(!opts.dom.clientWidth && (!opts || opts.width == null)) ||
|
||||||
|
(!opts.dom.clientHeight && (!opts || opts.height == null))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
console.warn('Can\'t get DOM width or height. Please check ' +
|
||||||
|
'dom.clientWidth and dom.clientHeight. They should not be 0.' +
|
||||||
|
'For example, you may need to call this in the callback ' +
|
||||||
|
'of window.onload.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = new JMap(opts);
|
||||||
|
|
||||||
|
this.instances[opts.el] = map;
|
||||||
|
|
||||||
|
Dom.setAttribute(opts.dom, DOM_ATTRIBUTE_KEY, opts.el);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVersion() {
|
||||||
|
return this._version;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstanceByDom(dom) {
|
||||||
|
return this.instances[Dom.getAttribute(dom, DOM_ATTRIBUTE_KEY)];
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstanceById(el) {
|
||||||
|
return this.instances[el];
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(map) {
|
||||||
|
if (utils.isString(map)) {
|
||||||
|
map = this.instances[map];
|
||||||
|
} else if (!utils.isInstanceOf(map, map)) {
|
||||||
|
map = this.getInstanceByDom(map.getDom());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
map.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
Object.values(this.instances).forEach(map => {
|
||||||
|
this.dispose(map);
|
||||||
|
})
|
||||||
|
this.instances = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JMaps;
|
62
src/iscs_new/option.js
Normal file
62
src/iscs_new/option.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
class Option {
|
||||||
|
constructor(opts, notice) {
|
||||||
|
this.ratio = 100;
|
||||||
|
|
||||||
|
this.step = 0.1;
|
||||||
|
|
||||||
|
this.scaleMin = 0.3;
|
||||||
|
|
||||||
|
this.scaleMax = 10;
|
||||||
|
|
||||||
|
this.scaleRate = opts.scaleRate || 1; // 缩放
|
||||||
|
|
||||||
|
this.offsetX = opts.offsetX || 0; // x偏移
|
||||||
|
|
||||||
|
this.offsetY = opts.offsetY || 0; // y偏移
|
||||||
|
|
||||||
|
this.rotation = opts.rotation || 0; // 旋转弧度
|
||||||
|
|
||||||
|
this.throttle = opts.throttle || 100; // 刷新频率
|
||||||
|
|
||||||
|
this.preventDefaultMouseMove = true;
|
||||||
|
|
||||||
|
this.notice = notice;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(payload) {
|
||||||
|
if (Number.isFinite(payload.dx)) {
|
||||||
|
this.offsetX -= payload.dx;
|
||||||
|
}
|
||||||
|
if (Number.isFinite(payload.dy)) {
|
||||||
|
this.offsetY -= payload.dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isFinite(payload.offsetX)) {
|
||||||
|
this.offsetX = payload.offsetX;
|
||||||
|
}
|
||||||
|
if (Number.isFinite(payload.offsetY)) {
|
||||||
|
this.offsetY = payload.offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isFinite(payload.scale)) {
|
||||||
|
this.scaleRate = this.getScaleRate(payload.scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isFinite(payload.scaleRate)) {
|
||||||
|
this.scaleRate = payload.scaleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.notice instanceof Function) { this.notice(this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
getScaleRate(scale) {
|
||||||
|
if (Number.isFinite(scale)) {
|
||||||
|
const sumScaleNum = parseInt((this.scaleRate - this.scaleMin + scale * this.step) * this.ratio);
|
||||||
|
const maxScaleNum = this.scaleMax * this.ratio;
|
||||||
|
return sumScaleNum > 0? ((sumScaleNum%maxScaleNum) / this.ratio + this.scaleMin).toFixed(1): this.scaleRate;
|
||||||
|
}
|
||||||
|
return this.scaleRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Option;
|
117
src/iscs_new/painter.js
Normal file
117
src/iscs_new/painter.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import * as graphic from './core/graphic';
|
||||||
|
import shapeLayer from './constant/shapeLayer';
|
||||||
|
import Group from 'zrender/src/container/Group';
|
||||||
|
import TransformHandle from './transformHandle';
|
||||||
|
import AnimateHandle from './animateHandle';
|
||||||
|
|
||||||
|
class Painter extends Group {
|
||||||
|
constructor(map) {
|
||||||
|
super({name: `__Container__` });
|
||||||
|
// 添加父级图层
|
||||||
|
const zr = map.getZr();
|
||||||
|
zr.add(this);
|
||||||
|
|
||||||
|
// 初始图层
|
||||||
|
this.initLevels(map);
|
||||||
|
|
||||||
|
// 视图控制器
|
||||||
|
this.$transformHandle = new TransformHandle(this);
|
||||||
|
|
||||||
|
// 动画处理器
|
||||||
|
this.$animateHandle = new AnimateHandle(this);
|
||||||
|
|
||||||
|
// 重写onFrame加入钩子
|
||||||
|
this.onframe(zr);
|
||||||
|
}
|
||||||
|
|
||||||
|
onframe(zr) {
|
||||||
|
const onframe = zr.animation.onframe;
|
||||||
|
const animateHandle = this.$animateHandle;
|
||||||
|
zr.animation.onframe = interval => {
|
||||||
|
onframe.call(zr.animation, interval);
|
||||||
|
animateHandle.onframe(interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initLevels(map) {
|
||||||
|
// 初始化图层对象
|
||||||
|
this.mapShapeLayer = {};
|
||||||
|
|
||||||
|
// 创建select图层
|
||||||
|
this.mapShapeLayer[shapeLayer.Selecting] = new Group({ name: shapeLayer.Selecting });
|
||||||
|
|
||||||
|
// 创建hover图层
|
||||||
|
this.mapShapeLayer[shapeLayer.HightLight] = new Group({ name: shapeLayer.HightLight });
|
||||||
|
|
||||||
|
// 创建tips图层
|
||||||
|
this.mapShapeLayer[shapeLayer.Tips] = new Group({name: shapeLayer.Tips });
|
||||||
|
|
||||||
|
// 创建元素图层
|
||||||
|
Object.keys(graphic).forEach(key => {
|
||||||
|
this.mapShapeLayer[key] = new Group({
|
||||||
|
name: `__${key}__`
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加图层
|
||||||
|
Object.values(this.mapShapeLayer).forEach(el => {
|
||||||
|
super.add(el);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
add(shape) {
|
||||||
|
shape && this.removeFromLayer(shapeLayer.HightLight, shape.instanceHightLight);
|
||||||
|
shape && this.addToLayer(shape.type, shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(shape) {
|
||||||
|
shape && this.removeFromLayer(shapeLayer.HightLight, shape.instanceHightLight);
|
||||||
|
shape && this.removeFromLayer(shape.type, shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
update(stateList=[]) {
|
||||||
|
stateList
|
||||||
|
.sort((a,b) => a.weight - b.weight)
|
||||||
|
.forEach(state => {
|
||||||
|
this.$animateHandle.animate(state);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTransform(opt) {
|
||||||
|
this.$transformHandle.updateTransform(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateZrSize(opt) {
|
||||||
|
this.$transformHandle.updateZrSize(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
addToLayer(name, shape) {
|
||||||
|
name = Object.keys(graphic).includes(name)? name: `Group`;
|
||||||
|
this.mapShapeLayer[name].add(shape);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromLayer(name, shape) {
|
||||||
|
name = Object.keys(graphic).includes(name)? name: `Group`;
|
||||||
|
this.mapShapeLayer[name].remove(shape);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLevelByName(name) {
|
||||||
|
return this.mapShapeLayer[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
Object.values(this.mapShapeLayer).forEach(el => {
|
||||||
|
el.removeAll();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.clear();
|
||||||
|
this.mapShapeLayer = {};
|
||||||
|
this.mapAnimate = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Painter;
|
111
src/iscs_new/plugins/shapeBuilder/entry.vue
Normal file
111
src/iscs_new/plugins/shapeBuilder/entry.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="builder" v-show="visible">
|
||||||
|
<div class="container">
|
||||||
|
<el-button-group>
|
||||||
|
<el-button v-for="(type,i) in graphicType" :key="i" @click="doBuilder(type)">
|
||||||
|
{{type}}
|
||||||
|
</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as graphic from '../../core/graphic';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import elementConst from '@/iscs_new/core/form/elementConst';
|
||||||
|
import formBuilder from '@/iscs_new/core/form/formBuilder';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
const exec = (fm, name, ...args) => fm && fm[name] && fm[name](...args);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: true,
|
||||||
|
enum: 'Compose',
|
||||||
|
graphicType: [],
|
||||||
|
strategyMap: {
|
||||||
|
'Compose': {
|
||||||
|
init: () => {
|
||||||
|
this.graphicType = Object.fromEntries(Object.keys(graphic).filter(type => !['Group'].includes(type)).map(type => [type, type]))
|
||||||
|
},
|
||||||
|
doBuilder: (type) => {
|
||||||
|
const form = formBuilder.buildForm(elementConst[type]);
|
||||||
|
const model = utils.deepClone(form.model);
|
||||||
|
model.code = utils.getUID(type);
|
||||||
|
model.type = type;
|
||||||
|
model.name = '<名称>';
|
||||||
|
model.base.position = [300, 100];
|
||||||
|
model.stateList = [];
|
||||||
|
this.$iscs && this.$iscs.render([{model, action: {shapeType: shapeType.Element, order: orders.Add}}]);
|
||||||
|
EventBus.$emit('getComposeElemList');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Map': {
|
||||||
|
init: () =>{
|
||||||
|
|
||||||
|
},
|
||||||
|
doBuilder: (type) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
exec(this.strategyMap[this.enum], 'init')
|
||||||
|
},
|
||||||
|
doBuilder(type) {
|
||||||
|
exec(this.strategyMap[this.enum], 'doBuilder', type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.builder {
|
||||||
|
background: #f1f1f1;
|
||||||
|
height: 100%;
|
||||||
|
width: 130px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
/*滚动条整体样式*/
|
||||||
|
width : 5px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
/*滚动条里面小方块*/
|
||||||
|
border-radius : 10px;
|
||||||
|
background-color: lightskyblue;
|
||||||
|
background-image: -webkit-linear-gradient(
|
||||||
|
45deg,
|
||||||
|
rgba(255, 255, 255, 0.2) 25%,
|
||||||
|
transparent 25%,
|
||||||
|
transparent 50%,
|
||||||
|
rgba(255, 255, 255, 0.2) 50%,
|
||||||
|
rgba(255, 255, 255, 0.2) 75%,
|
||||||
|
transparent 75%,
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
/*滚动条里面轨道*/
|
||||||
|
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background : #ededed;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
67
src/iscs_new/plugins/shapeBuilder/index.js
Normal file
67
src/iscs_new/plugins/shapeBuilder/index.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import events from '@/iscs_new/utils/events';
|
||||||
|
import entry from './entry.vue';
|
||||||
|
|
||||||
|
const VuePage = Vue.extend(entry);
|
||||||
|
|
||||||
|
const handle = {
|
||||||
|
onClick(e) {
|
||||||
|
if (!e) {
|
||||||
|
this.page.type = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onContextMenu(e) {
|
||||||
|
if (!e) {
|
||||||
|
this.page.type = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ShapeBuilder {
|
||||||
|
constructor(map) {
|
||||||
|
this.zr = map.getZr();
|
||||||
|
this.map = map;
|
||||||
|
this.page = this.initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
initUI() {
|
||||||
|
const el = this.zr.dom;
|
||||||
|
const page = new VuePage({
|
||||||
|
el: document.createElement('div'),
|
||||||
|
data () {}
|
||||||
|
});
|
||||||
|
|
||||||
|
el.page = page;
|
||||||
|
el.dom = page.$el;
|
||||||
|
el.grSelectStyle = {};
|
||||||
|
el.appendChild(el.dom);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.on(events.Click, handle.onClick, this);
|
||||||
|
this.map.on(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.off(events.Click, handle.onClick, this);
|
||||||
|
this.map.off(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
el: null,
|
||||||
|
install(map) {
|
||||||
|
this.el = new ShapeBuilder(map);
|
||||||
|
this.el.addEventListener();
|
||||||
|
},
|
||||||
|
uninstall(map) {
|
||||||
|
if (this.el) {
|
||||||
|
this.el.removeEventListener();
|
||||||
|
this.el = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
208
src/iscs_new/plugins/shapeContextMenu/entry.vue
Normal file
208
src/iscs_new/plugins/shapeContextMenu/entry.vue
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div v-if="visible" class="menus" :style="{ left: position.x+'px', top: position.y+'px' }">
|
||||||
|
<menu-item v-for="(el, i) in menus" :key="i" :option="el" @close="doClose" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MenuItem from './menu-item';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
MenuItem
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: true,
|
||||||
|
selected: null,
|
||||||
|
breforePosition: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
clipboardList: [],
|
||||||
|
menus: [],
|
||||||
|
menusMap: {
|
||||||
|
Normal: [
|
||||||
|
{
|
||||||
|
label: '组合',
|
||||||
|
handler: this.doBinding,
|
||||||
|
disabledCb: e => {
|
||||||
|
const storage = this.$iscs.getController().getStorage();
|
||||||
|
return storage.values().length <= 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '解组',
|
||||||
|
handler: this.doUnBinding,
|
||||||
|
disabledCb: e => {
|
||||||
|
return this.selected.shapeType != shapeType.Compose;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '复制',
|
||||||
|
handler: this.doCopy,
|
||||||
|
disabledCb: e => {
|
||||||
|
const storage = this.$iscs.getController().getStorage();
|
||||||
|
return !storage.values().length;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
handler: this.doDelete,
|
||||||
|
disabledCb: e => {
|
||||||
|
const storage = this.$iscs.getController().getStorage();
|
||||||
|
return !storage.values().length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
None: [
|
||||||
|
{
|
||||||
|
label: '粘贴',
|
||||||
|
handler: this.doPaste,
|
||||||
|
disabledCb: e => {
|
||||||
|
return !this.clipboardList.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doShow(point, code) {
|
||||||
|
const list = code ? this.menusMap.Normal: this.menusMap.None;
|
||||||
|
this.selected= this.$iscs.getShapeByCode(code);
|
||||||
|
this.menus = list.map(el => { el.disabled = el.disabledCb({}); return el} );
|
||||||
|
if (this.menus &&
|
||||||
|
this.menus.length) {
|
||||||
|
this.position = {...point},
|
||||||
|
this.visible = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doClose() {
|
||||||
|
this.selected = null;
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
doBinding(el) {
|
||||||
|
const controller = this.$iscs.getController();
|
||||||
|
const storage = controller.getStorage()
|
||||||
|
const values = storage.values();
|
||||||
|
if (values.length > 1) {
|
||||||
|
const elem = {
|
||||||
|
model: {
|
||||||
|
code: utils.getUID('compose'),
|
||||||
|
type: 'Device',
|
||||||
|
elementCodes: values.map(el => el.model.code),
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
composeCode: '',
|
||||||
|
},
|
||||||
|
action: { order: orders.Binding, shapeType: shapeType.Compose }
|
||||||
|
}
|
||||||
|
this.$iscs.render([elem]);
|
||||||
|
} else {
|
||||||
|
this.$message.info('请选择两个及其以上数目元素');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doUnBinding(el) {
|
||||||
|
if (this.selected) {
|
||||||
|
this.$iscs.render([
|
||||||
|
{
|
||||||
|
model: this.selected.model,
|
||||||
|
action: { order: orders.Unbinding, shapeType: shapeType.Compose }
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doCopy(el) {
|
||||||
|
const option = this.$iscs.getOption();
|
||||||
|
const storage = this.$iscs.getController().getStorage();
|
||||||
|
this.clipboardList = [...storage.values()];
|
||||||
|
this.breforePosition = {
|
||||||
|
x: this.position.x + option.offsetX,
|
||||||
|
y: this.position.y + option.offsetY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doPaste(el) {
|
||||||
|
const option = this.$iscs.getOption();
|
||||||
|
const renderList = [];
|
||||||
|
const clipboardList = [...this.clipboardList];
|
||||||
|
const diffPosition = [
|
||||||
|
(this.position.x + option.offsetX - this.breforePosition.x)/option.scaleRate,
|
||||||
|
(this.position.y + option.offsetY - this.breforePosition.y)/option.scaleRate
|
||||||
|
]
|
||||||
|
|
||||||
|
clipboardList.forEach(el => {
|
||||||
|
this.clone(el, utils.getUID(el.type), '', el => {
|
||||||
|
const shapeType = el.shapeType;
|
||||||
|
const model = el.model;
|
||||||
|
const position = model.base.position||[0, 0];
|
||||||
|
model.base.position = model.composeCode? position: position.map((el,i) => el+diffPosition[i]);
|
||||||
|
renderList.push({ model, action: { order: orders.Add, shapeType } });
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$iscs.render(renderList);
|
||||||
|
},
|
||||||
|
doDelete(el) {
|
||||||
|
const storage = this.$iscs.getController().getStorage();
|
||||||
|
const renderList = storage.values().map(el => {
|
||||||
|
return {
|
||||||
|
model: el.model,
|
||||||
|
action: { order: orders.Delete, shapeType: el.shapeType }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.$iscs.render(renderList);
|
||||||
|
},
|
||||||
|
clone(el, code='', composeCode='', cb) {
|
||||||
|
const model = utils.deepClone(el.model);
|
||||||
|
model.code = code;
|
||||||
|
model.composeCode = composeCode;
|
||||||
|
if (el.shapeType == shapeType.Compose) {
|
||||||
|
model.elementCodes = model.elementCodes.map(code => {
|
||||||
|
const shape = this.$iscs.getShapeByCode(code);
|
||||||
|
const newCode = utils.getUID(shape.type)
|
||||||
|
this.clone(shape, newCode, code, cb);
|
||||||
|
return newCode;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
cb({...el, model});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 2000;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
.menus {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: all;
|
||||||
|
background: #f1f1f1;
|
||||||
|
box-shadow: 0 2px 12px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
67
src/iscs_new/plugins/shapeContextMenu/index.js
Normal file
67
src/iscs_new/plugins/shapeContextMenu/index.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import events from '@/iscs_new/utils/events';
|
||||||
|
import entry from './entry.vue';
|
||||||
|
|
||||||
|
const elPage = Vue.extend(entry);
|
||||||
|
|
||||||
|
const handle = {
|
||||||
|
onClick(e) {
|
||||||
|
if (this.page) {
|
||||||
|
this.page.doClose()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onContextMenu(e) {
|
||||||
|
if (this.page) {
|
||||||
|
this.page.doShow({x: e.clientX, y: e.clientY}, e.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShapeBuilder {
|
||||||
|
constructor(map) {
|
||||||
|
this.zr = map.getZr();
|
||||||
|
this.map = map;
|
||||||
|
this.page = this.initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
initUI() {
|
||||||
|
const el = this.zr.dom;
|
||||||
|
const page = new elPage({
|
||||||
|
el: document.createElement('div'),
|
||||||
|
data () {}
|
||||||
|
});
|
||||||
|
el.page = page;
|
||||||
|
el.dom = page.$el;
|
||||||
|
el.grSelectStyle = {};
|
||||||
|
el.appendChild(el.dom);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.on(events.Click, handle.onClick, this);
|
||||||
|
this.map.on(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.off(events.Click, handle.onClick, this);
|
||||||
|
this.map.off(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
el: null,
|
||||||
|
install(map) {
|
||||||
|
this.el = new ShapeBuilder(map);
|
||||||
|
this.el.addEventListener();
|
||||||
|
},
|
||||||
|
uninstall(map) {
|
||||||
|
if (this.el) {
|
||||||
|
this.el.removeEventListener();
|
||||||
|
this.el = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
202
src/iscs_new/plugins/shapeContextMenu/menu-item.vue
Normal file
202
src/iscs_new/plugins/shapeContextMenu/menu-item.vue
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<template>
|
||||||
|
<li v-if="option.children && option.children.length" class="menu-item" @mouseenter="enter($vnode.key)" @mouseleave="leave">
|
||||||
|
<div ref="flexBox" class="flex-box">
|
||||||
|
<el-button type="text" class="item" :disabled="checkDisabled(option)">
|
||||||
|
<el-link v-if="option.tipsType" :type="option.tipsType" :underline="false">{{ option.label }}</el-link>
|
||||||
|
<span v-else :style="{color: textColor(option) }">{{ option.label }}</span>
|
||||||
|
</el-button>
|
||||||
|
<i class="el-icon-arrow-right" />
|
||||||
|
</div>
|
||||||
|
<ul v-if="isPopup" ref="popup" class="menu" :style="{display: isShow? 'block': 'table', marginLeft: marginLeft+'px'}">
|
||||||
|
<div class="menu-pop pop-menu">
|
||||||
|
<div v-show="isShow" class="arrow el-icon-arrow-down" />
|
||||||
|
<pop-menu-item v-for="(el, i) in option.children" :key="i" :option="el" :allowedColor="allowedColor" :disabledColor="disabledColor" @close="close" />
|
||||||
|
<div v-show="isShow" class="arrow el-icon-arrow-up" />
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li v-else-if="checkVisible(option)" class="menu-item" >
|
||||||
|
<div v-if="option.type === 'separator'" class="separator"> </div>
|
||||||
|
<el-button v-else-if="option.type ==='file'" type="text" class="uploadDemo item" :disabled="checkDisabled(option)">
|
||||||
|
<input :ref="option.label" type="file" class="file_box" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" @change="doHandle(option, true)">
|
||||||
|
<el-link v-if="option.tipsType" :type="option.tipsType" :underline="false">{{ option.label }} </el-link>
|
||||||
|
<span v-else :style="{color: textColor(option) }">{{ option.label }}</span>
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else type="text" class="item" :disabled="checkDisabled(option)" @click="doHandle(option, false)">
|
||||||
|
<el-link v-if="option.tipsType" :type="option.tipsType" :underline="false">{{ option.label }}</el-link>
|
||||||
|
<span v-else :style="{color: textColor(option) }">{{ option.label }}</span>
|
||||||
|
</el-button>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PopMenuItem',
|
||||||
|
props: {
|
||||||
|
option: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabledColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#ccc',
|
||||||
|
},
|
||||||
|
allowedColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
active: -1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isPopup() {
|
||||||
|
return this.active == this.$vnode.key;
|
||||||
|
},
|
||||||
|
isShow() {
|
||||||
|
return this.option.children.length > 12;
|
||||||
|
},
|
||||||
|
marginLeft() {
|
||||||
|
return this.$refs.flexBox.offsetWidth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkDisabled(option) {
|
||||||
|
return option.disabled || this.disabled;
|
||||||
|
},
|
||||||
|
checkVisible(option) {
|
||||||
|
if (typeof (option.show) === 'undefined') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return option.show;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textColor(option) {
|
||||||
|
return this.checkDisabled(option) ? this.disabledColor : this.allowedColor;
|
||||||
|
},
|
||||||
|
doHandle(option, isFile) {
|
||||||
|
if (option.handler && !this.checkDisabled(option)) {
|
||||||
|
if (isFile) {
|
||||||
|
const obj = this.$refs[option.label][0];
|
||||||
|
if (obj.files) {
|
||||||
|
const file = obj.files[0];
|
||||||
|
option.handler(file);
|
||||||
|
obj.value = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
option.handler(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$emit('close');
|
||||||
|
},
|
||||||
|
enter(active) {
|
||||||
|
this.active = active;
|
||||||
|
},
|
||||||
|
leave(e) {
|
||||||
|
this.active = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
$bg: #FFFFFF;
|
||||||
|
$item-hover: #CFE8FC;
|
||||||
|
$item-text: #606266;
|
||||||
|
$item-separator: #666;
|
||||||
|
$item-border: #909399;
|
||||||
|
$item-disabled: #cccccc;
|
||||||
|
$item-height: 30px;
|
||||||
|
|
||||||
|
/deep/ {
|
||||||
|
.el-button--text {
|
||||||
|
padding: 6px 15px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -$item-height - 1;
|
||||||
|
max-height: 360px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
&-pop {
|
||||||
|
display:table;
|
||||||
|
border: 1px solid $item-border;
|
||||||
|
.arrow {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
background: $bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-box{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
padding-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
list-style: none;
|
||||||
|
min-width: 110px;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background: $item-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
background: $item-separator;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
color: $item-text;
|
||||||
|
height: $item-height;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadDemo {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
color: $item-text;
|
||||||
|
|
||||||
|
input {
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
36
src/iscs_new/plugins/shapeProperty/entry.vue
Normal file
36
src/iscs_new/plugins/shapeProperty/entry.vue
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
class="property"
|
||||||
|
title="我是标题"
|
||||||
|
:modal="false"
|
||||||
|
:visible.sync="visible"
|
||||||
|
:with-header="false">
|
||||||
|
<div class="container">
|
||||||
|
<span>我来啦!</span>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: true
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.property {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
.container {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
77
src/iscs_new/plugins/shapeProperty/index.js
Normal file
77
src/iscs_new/plugins/shapeProperty/index.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import events from '@/iscs_new/utils/events';
|
||||||
|
import entry from './entry.vue';
|
||||||
|
|
||||||
|
const elPage = Vue.extend(entry);
|
||||||
|
|
||||||
|
const toggling = (page, e) => {
|
||||||
|
if (!!e) {
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
page.visible = true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
page.visible = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handle = {
|
||||||
|
onClick(e) {
|
||||||
|
toggling(this.page, e);
|
||||||
|
},
|
||||||
|
onContextMenu(e) {
|
||||||
|
},
|
||||||
|
onModify(e) {
|
||||||
|
},
|
||||||
|
onDelete(e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShapeBuilder {
|
||||||
|
constructor(map) {
|
||||||
|
this.zr = map.getZr();
|
||||||
|
this.map = map;
|
||||||
|
this.page = this.initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
initUI() {
|
||||||
|
const el = this.zr.dom;
|
||||||
|
const page = new elPage({
|
||||||
|
el: document.createElement('div'),
|
||||||
|
data () {}
|
||||||
|
});
|
||||||
|
el.page = page;
|
||||||
|
el.dom = page.$el;
|
||||||
|
el.grSelectStyle = {};
|
||||||
|
el.appendChild(el.dom);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.on(events.Click, handle.onClick, this);
|
||||||
|
this.map.on(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.off(events.Click, handle.onClick, this);
|
||||||
|
this.map.off(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
el: null,
|
||||||
|
install(map) {
|
||||||
|
this.el = new ShapeBuilder(map);
|
||||||
|
this.el.addEventListener();
|
||||||
|
},
|
||||||
|
uninstall(map) {
|
||||||
|
if (this.el) {
|
||||||
|
this.el.removeEventListener();
|
||||||
|
this.el = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
src/iscs_new/plugins/shapeState/entry.vue
Normal file
79
src/iscs_new/plugins/shapeState/entry.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div class="builder" v-show="visible">
|
||||||
|
<div class="container">
|
||||||
|
////
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as graphic from '../../core/graphic';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import elementConst from '@/iscs_new/core/form/elementConst';
|
||||||
|
import formBuilder from '@/iscs_new/core/form/formBuilder';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
visible: true,
|
||||||
|
graphicType: Object.fromEntries(Object.keys(graphic).filter(type => !['Group'].includes(type)).map(type => [type, type]))
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doBuilder(type) {
|
||||||
|
const form = formBuilder.buildForm(elementConst[type]);
|
||||||
|
const model = utils.deepClone(form.model);
|
||||||
|
model.code = utils.getUID(type);
|
||||||
|
model.type = type;
|
||||||
|
model.name = '<名称>';
|
||||||
|
model.base.position = [300, 100];
|
||||||
|
model.stateList = [];
|
||||||
|
this.$iscs && this.$iscs.render([{model, action: {shapeType: shapeType.Element, order: orders.Add}}]);
|
||||||
|
EventBus.$emit('getComposeElemList');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.builder {
|
||||||
|
background: #f1f1f1;
|
||||||
|
height: 100%;
|
||||||
|
width: 130px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
/*滚动条整体样式*/
|
||||||
|
width : 5px;
|
||||||
|
/*高宽分别对应横竖滚动条的尺寸*/
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
/*滚动条里面小方块*/
|
||||||
|
border-radius : 10px;
|
||||||
|
background-color: lightskyblue;
|
||||||
|
background-image: -webkit-linear-gradient(
|
||||||
|
45deg,
|
||||||
|
rgba(255, 255, 255, 0.2) 25%,
|
||||||
|
transparent 25%,
|
||||||
|
transparent 50%,
|
||||||
|
rgba(255, 255, 255, 0.2) 50%,
|
||||||
|
rgba(255, 255, 255, 0.2) 75%,
|
||||||
|
transparent 75%,
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
/*滚动条里面轨道*/
|
||||||
|
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
|
||||||
|
background : #ededed;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
67
src/iscs_new/plugins/shapeState/index.js
Normal file
67
src/iscs_new/plugins/shapeState/index.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import events from '@/iscs_new/utils/events';
|
||||||
|
import entry from './entry.vue';
|
||||||
|
|
||||||
|
const VuePage = Vue.extend(entry);
|
||||||
|
|
||||||
|
const handle = {
|
||||||
|
onClick(e) {
|
||||||
|
if (!e) {
|
||||||
|
this.page.type = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onContextMenu(e) {
|
||||||
|
if (!e) {
|
||||||
|
this.page.type = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ShapeBuilder {
|
||||||
|
constructor(map) {
|
||||||
|
this.zr = map.getZr();
|
||||||
|
this.map = map;
|
||||||
|
this.page = this.initUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
initUI() {
|
||||||
|
const el = this.zr.dom;
|
||||||
|
const page = new VuePage({
|
||||||
|
el: document.createElement('div'),
|
||||||
|
data () {}
|
||||||
|
});
|
||||||
|
|
||||||
|
el.page = page;
|
||||||
|
el.dom = page.$el;
|
||||||
|
el.grSelectStyle = {};
|
||||||
|
el.appendChild(el.dom);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.on(events.Click, handle.onClick, this);
|
||||||
|
this.map.on(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener() {
|
||||||
|
if (this.map) {
|
||||||
|
this.map.off(events.Click, handle.onClick, this);
|
||||||
|
this.map.off(events.ContextMenu, handle.onContextMenu, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
el: null,
|
||||||
|
install(map) {
|
||||||
|
this.el = new ShapeBuilder(map);
|
||||||
|
this.el.addEventListener();
|
||||||
|
},
|
||||||
|
uninstall(map) {
|
||||||
|
if (this.el) {
|
||||||
|
this.el.removeEventListener();
|
||||||
|
this.el = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
src/iscs_new/selectHandle.js
Normal file
58
src/iscs_new/selectHandle.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import shapeLayer from './constant/shapeLayer';
|
||||||
|
export default class SelectHandle {
|
||||||
|
constructor(map, controller) {
|
||||||
|
this.$map = map;
|
||||||
|
this.$zr = map.getZr();
|
||||||
|
this.$controller = controller;
|
||||||
|
this.$painter = map.getPainter();
|
||||||
|
|
||||||
|
this.e = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelected(e) {
|
||||||
|
if (e.target) {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
this.e = {...e};
|
||||||
|
if ([`Control`].includes(this.$controller.getKeyStr())) {
|
||||||
|
if (this.$controller.isSelected(e.target.code)) {
|
||||||
|
this.$controller.setTarget(null);
|
||||||
|
this.delSelected(e.target);
|
||||||
|
} else {
|
||||||
|
this.addSelected(e.target);
|
||||||
|
}
|
||||||
|
} else if (!storage.has(e.target.code)){
|
||||||
|
this.clear();
|
||||||
|
this.addSelected(e.target);
|
||||||
|
} else {
|
||||||
|
this.addSelected(e.target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addSelected(target) {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
storage.set(target.code, target);
|
||||||
|
target.shapeFactory.showHightLight(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
delSelected(target) {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
target.shapeFactory.hideHightLight(target);;
|
||||||
|
storage.delete(target.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
storage.values().forEach(target => {
|
||||||
|
this.delSelected(target);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDraggable(draggable) {
|
||||||
|
const target = this.e.target;
|
||||||
|
if (target &&
|
||||||
|
target.highLightInstance) {
|
||||||
|
target.highLightInstance.setDraggable(draggable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
293
src/iscs_new/selectingHandle.js
Normal file
293
src/iscs_new/selectingHandle.js
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
import * as graphic from './core/graphic.js';
|
||||||
|
import shapeRender from './constant/shapeRender';
|
||||||
|
import shapeLayer from './constant/shapeLayer';
|
||||||
|
import events from './utils/events.js';
|
||||||
|
import defaultStyle from './config/defaultStyle';
|
||||||
|
|
||||||
|
const vernierStyle = {
|
||||||
|
area: {
|
||||||
|
areaStyle: {
|
||||||
|
fill: `rgba(200,200,200,0.3)`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
strokeNoScale: true,
|
||||||
|
lineWidth: 30,
|
||||||
|
stroke: 'rgba(255,255,255,0.6)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
distance: 18,
|
||||||
|
length: 5,
|
||||||
|
lineStyle: {
|
||||||
|
strokeNoScale: true,
|
||||||
|
lineWidth: 2,
|
||||||
|
stroke: '#000000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
distance: 5,
|
||||||
|
textStyle: {
|
||||||
|
strokeNoScale: true,
|
||||||
|
textStroke: '#000',
|
||||||
|
textAlign: 'center',
|
||||||
|
textVerticalAlign: 'center'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vernier extends graphic.Group {
|
||||||
|
constructor(args) {
|
||||||
|
super(args);
|
||||||
|
this._scaleRate = 1;
|
||||||
|
this._area = null;
|
||||||
|
this._axisLineX = null;
|
||||||
|
this._axisLineY = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createArea(rect) {
|
||||||
|
this._area = new graphic.Rect({
|
||||||
|
subType: '@ignore',
|
||||||
|
...shapeRender,
|
||||||
|
z: 9999,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
...rect
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.area.areaStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.add(this._area);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createLineAxisX(rect) {
|
||||||
|
const minX = rect.x;
|
||||||
|
const minY = rect.y;
|
||||||
|
const maxX = rect.x + rect.width;
|
||||||
|
const maxY = rect.y + rect.height;
|
||||||
|
const directionX = (Math.abs(rect.width)/rect.width);
|
||||||
|
const directionY = (Math.abs(rect.height)/rect.height);
|
||||||
|
const axisLineWidthHalf = vernierStyle.axisLine.lineStyle.lineWidth/this._scaleRate/2;
|
||||||
|
|
||||||
|
this._axisLineX = new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 9999,
|
||||||
|
silent: true,
|
||||||
|
position: [0, -axisLineWidthHalf*directionY],
|
||||||
|
shape: {
|
||||||
|
x1: minX,
|
||||||
|
y1: minY,
|
||||||
|
x2: maxX,
|
||||||
|
y2: minY
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisLine.lineStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const step = vernierStyle.axisTick.lineStyle.lineWidth*2/this._scaleRate;
|
||||||
|
const count = parseInt(Math.abs(rect.width/step));
|
||||||
|
|
||||||
|
for(var i = 0; i in new Array(count+1).fill(0); i++) {
|
||||||
|
const offset = step * i * directionX;
|
||||||
|
const tick = i % vernierStyle.axisTick.length == 0
|
||||||
|
const len = tick? vernierStyle.axisTick.distance*0.7: vernierStyle.axisTick.distance*0.4;
|
||||||
|
if (tick) {
|
||||||
|
this.add(new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 10000,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
x1: minX + offset,
|
||||||
|
y1: minY,
|
||||||
|
x2: minX + offset,
|
||||||
|
y2: minY - len * directionY / this._scaleRate
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisTick.lineStyle,
|
||||||
|
...vernierStyle.axisLabel.textStyle,
|
||||||
|
text: i%2? '': i/vernierStyle.axisTick.length/2,
|
||||||
|
textPosition: directionY > 0? 'top': 'bottom'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
this.add(new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 10000,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
x1: minX + offset,
|
||||||
|
y1: minY,
|
||||||
|
x2: minX + offset,
|
||||||
|
y2: minY - len * directionY / this._scaleRate
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisTick.lineStyle
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.add(this._axisLineX);
|
||||||
|
}
|
||||||
|
|
||||||
|
_createLineAxisY(rect) {
|
||||||
|
const minX = rect.x;
|
||||||
|
const minY = rect.y;
|
||||||
|
const maxX = rect.x + rect.width;
|
||||||
|
const maxY = rect.y + rect.height;
|
||||||
|
const directionX = (Math.abs(rect.width)/rect.width);
|
||||||
|
const directionY = (Math.abs(rect.height)/rect.height);
|
||||||
|
const axisLineWidthHalf = vernierStyle.axisLine.lineStyle.lineWidth/this._scaleRate/2;
|
||||||
|
|
||||||
|
this._axisLineY = new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 9999,
|
||||||
|
silent: true,
|
||||||
|
position: [-axisLineWidthHalf*directionX, 0],
|
||||||
|
shape: {
|
||||||
|
x1: minX,
|
||||||
|
y1: minY,
|
||||||
|
x2: minX,
|
||||||
|
y2: maxY
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisLine.lineStyle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.add(this._axisLineY);
|
||||||
|
|
||||||
|
|
||||||
|
const step = vernierStyle.axisTick.lineStyle.lineWidth*2 /this._scaleRate;
|
||||||
|
const count = parseInt(Math.abs(rect.height/step));
|
||||||
|
|
||||||
|
for(var i = 0; i in new Array(count+1).fill(0); i++) {
|
||||||
|
const offset = step * i * directionY;
|
||||||
|
const tick = i % vernierStyle.axisTick.length == 0;
|
||||||
|
const len = tick? vernierStyle.axisTick.distance*0.7: vernierStyle.axisTick.distance*0.4;
|
||||||
|
if (tick) {
|
||||||
|
this.add(new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 10000,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
x1: minX,
|
||||||
|
y1: minY + offset,
|
||||||
|
x2: minX - len * directionX / this._scaleRate,
|
||||||
|
y2: minY + offset
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisTick.lineStyle,
|
||||||
|
...vernierStyle.axisLabel.textStyle,
|
||||||
|
text: i%2? '': i/vernierStyle.axisTick.length/2,
|
||||||
|
textPosition: directionX > 0? 'left': 'right'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
this.add(new graphic.Line({
|
||||||
|
...shapeRender,
|
||||||
|
z: 10000,
|
||||||
|
silent: true,
|
||||||
|
shape: {
|
||||||
|
x1: minX,
|
||||||
|
y1: minY + offset,
|
||||||
|
x2: minX - len * directionX / this._scaleRate,
|
||||||
|
y2: minY + offset
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
...vernierStyle.axisTick.lineStyle
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(rect) {
|
||||||
|
this.removeAll();
|
||||||
|
this._scaleRate = this.parent? this.parent.transform[0]: 1;
|
||||||
|
this._createArea(rect);
|
||||||
|
this._createLineAxisX(rect);
|
||||||
|
this._createLineAxisY(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShape(rect) {
|
||||||
|
this.render(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default class SelectingHandle {
|
||||||
|
constructor(map, controller) {
|
||||||
|
this.$map = map;
|
||||||
|
this.$zr = map.getZr();
|
||||||
|
this.$controller = controller;
|
||||||
|
this.$painter = map.getPainter();
|
||||||
|
|
||||||
|
this.begPoint = null;
|
||||||
|
this.endPoint = null;
|
||||||
|
this.selecting = new Vernier({subType: '@selecting'});
|
||||||
|
}
|
||||||
|
|
||||||
|
isSelecting() {
|
||||||
|
return this.begPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectStart(e) {
|
||||||
|
this.selecting.setShape({ x: e.x, y: e.y, width: 0, height: 0 });
|
||||||
|
this.$painter.addToLayer(shapeLayer.Selecting, this.selecting);
|
||||||
|
this.begPoint = { x: e.x, y: e.y };
|
||||||
|
this.endPoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelecting(e) {
|
||||||
|
this.endPoint = { x: e.x, y: e.y };
|
||||||
|
this.selecting.setShape(this.normalizedArea(this.begPoint, this.endPoint));
|
||||||
|
this.$painter.addToLayer(shapeLayer.Selecting, this.selecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectEnd(e) {
|
||||||
|
this.endPoint = { x: e.x, y: e.y };
|
||||||
|
this.selecting.setShape(this.normalizedArea(this.begPoint, this.endPoint));
|
||||||
|
this.$painter.addToLayer(shapeLayer.Selecting, this.selecting);
|
||||||
|
|
||||||
|
const selectingRect = this.selecting.getBoundingRect();
|
||||||
|
Object.values(this.$map.getMapShape()).forEach(el => {
|
||||||
|
if (el.model && !el.model.composeCode && this.checkSelectingRectContainShape(selectingRect, el)) {
|
||||||
|
this.setSelected(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelected(target) {
|
||||||
|
const storage = this.$controller.getStorage();
|
||||||
|
storage.set(target.code, target);
|
||||||
|
target.shapeFactory.showHightLight(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.$painter.removeFromLayer(shapeLayer.Selecting, this.selecting);
|
||||||
|
this.selecting.setShape({ x: 0, y: 0, width: 0, height: 0 });
|
||||||
|
this.begPoint = this.endPoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSelectingRectContainShape(rect, shape) {
|
||||||
|
const shapeRect = shape.getBoundingRect();
|
||||||
|
if (shapeRect) {
|
||||||
|
return rect.contain(shapeRect.x, shapeRect.y) && rect.contain(shapeRect.x+shapeRect.width, shapeRect.y+shapeRect.height);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizedArea(begin, end) {
|
||||||
|
const options = this.$map.getOption();
|
||||||
|
const x = (begin.x + options.offsetX) / options.scaleRate;
|
||||||
|
const y = (begin.y + options.offsetY) / options.scaleRate;
|
||||||
|
const width = (end.x - begin.x) / options.scaleRate;
|
||||||
|
const height = (end.y - begin.y) / options.scaleRate;
|
||||||
|
return {x, y, width, height};
|
||||||
|
}
|
||||||
|
}
|
63
src/iscs_new/stateHandle.js
Normal file
63
src/iscs_new/stateHandle.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import * as utils from './utils/utils';
|
||||||
|
|
||||||
|
export default class StateHandle {
|
||||||
|
constructor(map) {
|
||||||
|
this.$map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(shapeFactory, state) {
|
||||||
|
const mapTemplate = shapeFactory.getMapTemplate();
|
||||||
|
const template = mapTemplate[state.type];
|
||||||
|
const templateState = template.mapState[state.status] || {};
|
||||||
|
// const frameList = templateState.frameList||[];
|
||||||
|
const frameList = Object.values(templateState.covertStatusList) || [];
|
||||||
|
|
||||||
|
// 增加第一帧初始数据
|
||||||
|
// if (templateState &&
|
||||||
|
// templateState.needDefault) {
|
||||||
|
// templateState.frameList.unshift(
|
||||||
|
// Object.entries(template.mapShape).map(el => {
|
||||||
|
// return { name: el[0], ...el[1][utils.defStatus]};
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...templateState,
|
||||||
|
mapShape: template.mapShape,
|
||||||
|
shape: shapeFactory.getShapeByCode(state.code),
|
||||||
|
frameList: frameList.map(frame => {
|
||||||
|
// return Object.fromEntries(frame.map(el => {
|
||||||
|
return Object.fromEntries(frame.frameList.map((el, index) => {
|
||||||
|
const mapState = template.mapShape[el.name] || {};
|
||||||
|
const state = mapState[el.status] || {};
|
||||||
|
return [el.name || index, {
|
||||||
|
loop:frame.loop,
|
||||||
|
...el,
|
||||||
|
...state
|
||||||
|
}];
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
update(shapeFactory, states = []) {
|
||||||
|
return states.reduce((list, state) => {
|
||||||
|
return [
|
||||||
|
...list,
|
||||||
|
this.parse(shapeFactory, state) // 测试只有自身
|
||||||
|
// this.updateState(this.parse(shapeFactory, state)), // 处理自身
|
||||||
|
// this.updateState(this.parse(shapeFactory, state)) // 处理依赖
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState(state = {}) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDepState(state = {}) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
64
src/iscs_new/transformHandle.js
Normal file
64
src/iscs_new/transformHandle.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import * as utils from './utils/utils';
|
||||||
|
|
||||||
|
export default class TransformHandle {
|
||||||
|
constructor(painter) {
|
||||||
|
this.$painter = painter;
|
||||||
|
|
||||||
|
this.rect = { x: 0, y: 0, width: 0, height: 0 };
|
||||||
|
|
||||||
|
this.transform = utils.createTransform({scale:[1,1], position:[0,0], rotation:0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransform() {
|
||||||
|
return this.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查显隐
|
||||||
|
checkVisible(shape) {
|
||||||
|
return (!shape.model || !shape.model.base.hide || !shape.model.composeCode) && utils.createBoundingRectCheckVisible(shape, this.transform).intersect(this.rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新计算显隐
|
||||||
|
visibleView(shape) {
|
||||||
|
this.checkVisible(shape)
|
||||||
|
? shape.show()
|
||||||
|
: shape.hide();
|
||||||
|
shape.dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缩放/平移图层
|
||||||
|
transformAll() {
|
||||||
|
this.traverse(this.visibleView, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新偏移量
|
||||||
|
updateTransform(opt) {
|
||||||
|
this.transform = utils.createTransform({scale: [opt.scaleRate, opt.scaleRate], position: [-opt.offsetX/opt.scaleRate, -opt.offsetY/opt.scaleRate], rotation: 0});
|
||||||
|
this.transformAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新画布尺寸
|
||||||
|
updateZrSize(opt) {
|
||||||
|
this.rect = { x: 0, y: 0, width: opt.width, height: opt.height };
|
||||||
|
this.transformAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历view执行回调
|
||||||
|
traverse(cb, context) {
|
||||||
|
debugger
|
||||||
|
this.traverseLayer(layer => {
|
||||||
|
layer.eachChild(shape => {
|
||||||
|
cb.call(context, shape);
|
||||||
|
})
|
||||||
|
}, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历图层执行回调
|
||||||
|
traverseLayer(cb, context) {
|
||||||
|
this.$painter.eachChild(layer => {
|
||||||
|
layer.transform = this.transform;
|
||||||
|
cb.call(context, layer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/iscs_new/utils/dom.js
Normal file
17
src/iscs_new/utils/dom.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export function isDom(dom) {
|
||||||
|
return typeof dom === 'object' &&
|
||||||
|
typeof dom.nodeType === 'number' &&
|
||||||
|
typeof dom.ownerDocument === 'object';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setAttribute(dom, key, value) {
|
||||||
|
dom.setAttribute
|
||||||
|
? dom.setAttribute(key, value)
|
||||||
|
: (dom[key] = value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAttribute(dom, key) {
|
||||||
|
return dom.getAttribute
|
||||||
|
? dom.getAttribute(key)
|
||||||
|
: dom[key];
|
||||||
|
}
|
15
src/iscs_new/utils/events.js
Normal file
15
src/iscs_new/utils/events.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default {
|
||||||
|
Reflect: 'reflect',
|
||||||
|
Click: 'click',
|
||||||
|
ContextMenu: 'contextmenu',
|
||||||
|
DataZoom: 'dataZoom',
|
||||||
|
Keydown: 'keydown',
|
||||||
|
Keyup: 'keyup',
|
||||||
|
Keypress: 'keypress',
|
||||||
|
DataLoaded: 'dataLoaded',
|
||||||
|
ViewLoaded: 'viewLoaded',
|
||||||
|
StateLoaded: 'stateLoaded',
|
||||||
|
ViewUpdate: 'viewUpdate',
|
||||||
|
StateUpdate: 'stateUpdate',
|
||||||
|
OptionUpdate: 'optionUpdate'
|
||||||
|
}
|
9
src/iscs_new/utils/orders.js
Normal file
9
src/iscs_new/utils/orders.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export default {
|
||||||
|
Add: '&Add',
|
||||||
|
Delete: '&DEL',
|
||||||
|
Update: '&UPT',
|
||||||
|
Binding: '&Binding',
|
||||||
|
Unbinding: '&Unbinding',
|
||||||
|
ChangeStatus:'&ChangeStatus',
|
||||||
|
ResetStatus:'&ResetStatus'
|
||||||
|
};
|
63
src/iscs_new/utils/storage.js
Normal file
63
src/iscs_new/utils/storage.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
export default class Storage {
|
||||||
|
constructor() {
|
||||||
|
this.map = new Map();
|
||||||
|
this.lst = new Set();
|
||||||
|
this.clipboard = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
has(code) {
|
||||||
|
return code ? this.map.has(code) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(code, target) {
|
||||||
|
if (!this.has(code)) {
|
||||||
|
this.lst.add(code);
|
||||||
|
this.map.set(code, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(code) {
|
||||||
|
return this.map.get(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(code) {
|
||||||
|
if (this.has(code)) {
|
||||||
|
this.map.delete(code);
|
||||||
|
this.lst.delete(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
values() {
|
||||||
|
return Array.from(this.lst).map(code => { return this.get(code); });
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.lst.clear();
|
||||||
|
this.map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
isSelectExist(code) {
|
||||||
|
return this.has(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
forEach() {
|
||||||
|
return this.map.forEach;
|
||||||
|
}
|
||||||
|
|
||||||
|
setClipboard(lst) {
|
||||||
|
this.clipboard = Array.from(lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearClipboard() {
|
||||||
|
this.clipboard = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getClipboard() {
|
||||||
|
return this.clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
getClipboardSize() {
|
||||||
|
return this.clipboard.length;
|
||||||
|
}
|
||||||
|
}
|
111
src/iscs_new/utils/utils.js
Normal file
111
src/iscs_new/utils/utils.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import BoundingRect from 'zrender/src/core/BoundingRect';
|
||||||
|
import * as matrix from 'zrender/src/core/matrix';
|
||||||
|
|
||||||
|
// 默认状态标识
|
||||||
|
export const defStatus = 'default';
|
||||||
|
|
||||||
|
// 获取一个UID
|
||||||
|
export const getUID =(function(base=0) {
|
||||||
|
return function(type) { return [(type || ''), base++, Math.random().toFixed(5)].join('_');}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// 克隆一个对象
|
||||||
|
export function deepClone(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 克隆一个对象到另一个对象
|
||||||
|
export function deepAssign(tag, obj) {
|
||||||
|
return JSON.parse(JSON.stringify({...tag, ...obj}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝对象指定层次的引用
|
||||||
|
export function assignByDepth(source, target, depth) {
|
||||||
|
Object.keys(target).forEach(key => {
|
||||||
|
if (depth) {
|
||||||
|
Object.keys(target).forEach(key => {
|
||||||
|
source[key] = assignByDepth(source[key]||{}, target[key]||{}, depth-1);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
source[key] = target[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个transform
|
||||||
|
export function createTransform({scale=[1,1], position=[0,0], rotation=0}) {
|
||||||
|
let transform = matrix.create();
|
||||||
|
transform = matrix.translate(matrix.create(), transform, position);
|
||||||
|
transform = matrix.rotate(matrix.create(), transform, rotation);
|
||||||
|
transform = matrix.scale(matrix.create(), transform, scale);
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算自身缩放和偏移后的包围框
|
||||||
|
export function createBoundingRect(shape) {
|
||||||
|
const rect = shape.getBoundingRect().clone();
|
||||||
|
const scaleX = shape.scale[0];
|
||||||
|
const scaleY = shape.scale[1];
|
||||||
|
const offsetX = shape.position[0];
|
||||||
|
const offsetY = shape.position[1];
|
||||||
|
|
||||||
|
rect.x = rect.x * scaleX + offsetX;
|
||||||
|
rect.y = rect.y * scaleY + offsetY;
|
||||||
|
rect.width = rect.width * scaleX;
|
||||||
|
rect.height = rect.height * scaleY;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算变化计算包围框
|
||||||
|
export function createBoundingRectCheckVisible(shape, transform) {
|
||||||
|
const rect = shape.getBoundingRect();
|
||||||
|
const scaleX = transform[0];
|
||||||
|
const scaleY = transform[3];
|
||||||
|
const offsetX = transform[4];
|
||||||
|
const offsetY = transform[5];
|
||||||
|
|
||||||
|
rect.x = rect.x * scaleX + offsetX;
|
||||||
|
rect.y = rect.y * scaleY + offsetY;
|
||||||
|
rect.width = rect.width * scaleX;
|
||||||
|
rect.height = rect.height * scaleY;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算图形的旋转中心
|
||||||
|
export function createOrigin(shape) {
|
||||||
|
const rect = shape.getBoundingRect();
|
||||||
|
return [rect.x + rect.width/2, rect.y + rect.height/2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算视图中心
|
||||||
|
export function calculateDCenter(viewRect, bound) {
|
||||||
|
var dx = (bound.width - viewRect.width) / 2 - viewRect.x;
|
||||||
|
var dy = (bound.height - viewRect.height) / 2 - viewRect.y;
|
||||||
|
return { dx, dy };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 矩形碰撞检测
|
||||||
|
export function checkRectCollision(rect1, rect2) {
|
||||||
|
const center1 = { x: rect1.x + rect1.width / 2, y: rect1.y + rect1.height / 2 };
|
||||||
|
const center2 = { x: rect2.x + rect2.width / 2, y: rect2.y + rect2.height / 2 };
|
||||||
|
return Math.abs(center1.x - center2.x) < rect1.width / 2 + rect2.width / 2 && Math.abs(center1.y - center2.y) < rect1.height / 2 + rect2.height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过两点计算弧度
|
||||||
|
export function getRadian(point1, point2) {
|
||||||
|
return Math.atan2(point2.y-point1.y, point2.x-point1.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类型检测
|
||||||
|
const checkJsType = (type) => { return (obj) => { return Object.prototype.toString.call(obj) === `[object ${type.name}]`; }; };
|
||||||
|
|
||||||
|
export function isFunction() { return checkJsType(Function); }
|
||||||
|
|
||||||
|
export function isArray() { return checkJsType(Array); }
|
||||||
|
|
||||||
|
export function isString() { return checkJsType(String); }
|
||||||
|
|
||||||
|
export function isInstanceOf(obj, target) {
|
||||||
|
return obj instanceof target;
|
||||||
|
}
|
@ -27,7 +27,7 @@ class Signal extends Group {
|
|||||||
this._code = model.code;
|
this._code = model.code;
|
||||||
this._type = model._type;
|
this._type = model._type;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.mapDevice = mapDevice;
|
this.mapDevice = mapDevice;
|
||||||
this.style = style;
|
this.style = style;
|
||||||
this.count = parseInt(model.lampPositionType);
|
this.count = parseInt(model.lampPositionType);
|
||||||
this.lamps = new Array(this.count);
|
this.lamps = new Array(this.count);
|
||||||
@ -322,12 +322,12 @@ class Signal extends Group {
|
|||||||
const drict = this.model.right ? 1 : -1; // 朝向 左:右
|
const drict = this.model.right ? 1 : -1; // 朝向 左:右
|
||||||
const posit = this.model.positionType == '01' ? -1 : 1; // 位置 上:下
|
const posit = this.model.positionType == '01' ? -1 : 1; // 位置 上:下
|
||||||
// 信号机名称
|
// 信号机名称
|
||||||
const actual = this.mapDevice[model.linkSignalCode];
|
const actual = this.mapDevice[model.linkSignalCode];
|
||||||
const sigNameX = model.position.x + model.positionPoint.x + drict * 0.433 * style.Signal.transmission.sideLength + model.namePosition.x;
|
const sigNameX = model.position.x + model.positionPoint.x + drict * 0.433 * style.Signal.transmission.sideLength + model.namePosition.x;
|
||||||
const sigNameY = model.position.y + model.positionPoint.y + posit * (style.Signal.distance + style.Section.line.width + style.Signal.lamp.radiusR * 2 + model.namePosition.y + style.Signal.text.distance);
|
const sigNameY = model.position.y + model.positionPoint.y + posit * (style.Signal.distance + style.Section.line.width + style.Signal.lamp.radiusR * 2 + model.namePosition.y + style.Signal.text.distance);
|
||||||
const textAlign = style.Signal.text.isAlignCenter ? 'middle' : this.model.right ? 'left' : 'right';
|
const textAlign = style.Signal.text.isAlignCenter ? 'middle' : this.model.right ? 'left' : 'right';
|
||||||
const textVerticalAlign = posit == 1 ? 'top' : 'bottom';
|
const textVerticalAlign = posit == 1 ? 'top' : 'bottom';
|
||||||
const fillColor = actual.virtual? style.Signal.transmission.fillColorVirtual: style.Signal.transmission.fillColor;
|
const fillColor = actual.virtual ? style.Signal.transmission.fillColorVirtual : style.Signal.transmission.fillColor;
|
||||||
this.sigName = new ESigName({
|
this.sigName = new ESigName({
|
||||||
zlevel: this.zlevel,
|
zlevel: this.zlevel,
|
||||||
z: this.z,
|
z: this.z,
|
||||||
@ -511,12 +511,12 @@ class Signal extends Group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.style.Signal.lamp.guidName !== 'singleRY') {
|
if (this.style.Signal.lamp.guidName !== 'singleRY') {
|
||||||
if (this.lamps.length == 1) {
|
if (this.lamps.length == 1) {
|
||||||
this.lamps[0] && this.lamps[0].setColor(this.style.Signal.lamp.redColor);
|
this.lamps[0] && this.lamps[0].setColor(this.style.Signal.lamp.redColor);
|
||||||
} else {
|
} else {
|
||||||
this.lamps[0] && this.lamps[0].setColor(this.style.Signal.lamp.redColor);
|
this.lamps[0] && this.lamps[0].setColor(this.style.Signal.lamp.redColor);
|
||||||
this.lamps[1] && this.lamps[1].setColor(this.style.Signal.lamp.yellowColor);
|
this.lamps[1] && this.lamps[1].setColor(this.style.Signal.lamp.yellowColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -859,8 +859,8 @@ class Signal extends Group {
|
|||||||
default:
|
default:
|
||||||
var drict = this.model.right ? 1 : -1; // 朝向 右:左
|
var drict = this.model.right ? 1 : -1; // 朝向 右:左
|
||||||
var offsetY = this.model.positionType == '01' ? this.style.Signal.text.fontSize : 0; // 位置 上:下
|
var offsetY = this.model.positionType == '01' ? this.style.Signal.text.fontSize : 0; // 位置 上:下
|
||||||
var shape = this.model.type == 'TRANSMISSION'? this.transmission: this.sigPost;
|
var shape = this.model.type == 'TRANSMISSION' ? this.transmission : this.sigPost;
|
||||||
rect = shape.getBoundingRect().clone();
|
rect = shape.getBoundingRect().clone();
|
||||||
rect.x = rect.x + drict * this.style.Signal.post.standardVerticalWidth;
|
rect.x = rect.x + drict * this.style.Signal.post.standardVerticalWidth;
|
||||||
rect.y = rect.y - offsetY;
|
rect.y = rect.y - offsetY;
|
||||||
break;
|
break;
|
||||||
|
@ -30,6 +30,7 @@ const Jlmap3dOtherVR = () => import('@/views/jlmap3d/maintainer/jl3dothervr');
|
|||||||
// const Jl3dMaintainer = () => import('@/views/jlmap3d/maintainer/jl3dmaintainer');
|
// const Jl3dMaintainer = () => import('@/views/jlmap3d/maintainer/jl3dmaintainer');
|
||||||
|
|
||||||
const DisplayNew = () => import('@/views/newMap/displayNew/index');
|
const DisplayNew = () => import('@/views/newMap/displayNew/index');
|
||||||
|
const DisplayCity = () => import('@/views/newMap/displayCity/index');
|
||||||
const DesignDisplayNew = () => import('@/views/newMap/displayNew/scriptDisplay/scriptPreview/index');
|
const DesignDisplayNew = () => import('@/views/newMap/displayNew/scriptDisplay/scriptPreview/index');
|
||||||
const PracticeDisplay = () => import('@/views/newMap/displayNew/practiceDisplay');
|
const PracticeDisplay = () => import('@/views/newMap/displayNew/practiceDisplay');
|
||||||
const BigLPFStrategy = () => import('@/views/newMap/displayNew/bigLPFStrategy');
|
const BigLPFStrategy = () => import('@/views/newMap/displayNew/bigLPFStrategy');
|
||||||
@ -59,6 +60,11 @@ const IscsDesign = () => import('@/views/iscs/iscsDesign/index');
|
|||||||
const IscsConfig = () => import('@/views/iscs/iscsSystem/config/index');
|
const IscsConfig = () => import('@/views/iscs/iscsSystem/config/index');
|
||||||
const IscsStationConfig = () => import('@/views/iscs/iscsSystem/stationConfig/index');
|
const IscsStationConfig = () => import('@/views/iscs/iscsSystem/stationConfig/index');
|
||||||
|
|
||||||
|
const IscsNewDesign = () => import('@/views/iscs_new/iscsDesign/index');
|
||||||
|
const IscsNewDraw = () => import('@/views/iscs_new/iscsDraw/index');
|
||||||
|
const IscsNewPreview = () => import('@/views/iscs_new/iscsPreview/index');
|
||||||
|
|
||||||
|
|
||||||
const NewMapDraft = () => import('@/views/newMap/newMapdraft/index');
|
const NewMapDraft = () => import('@/views/newMap/newMapdraft/index');
|
||||||
const NewDesignPlatformUser = () => import('@/views/newMap/newDesignUser/index');
|
const NewDesignPlatformUser = () => import('@/views/newMap/newDesignUser/index');
|
||||||
|
|
||||||
@ -162,6 +168,7 @@ const RunPlanViewWindow = () => import('@/views/newMap/displayNew/demon/runPlanV
|
|||||||
const SecondaryHome = () => import('@/views/trainingPlatform/secondaryHome');
|
const SecondaryHome = () => import('@/views/trainingPlatform/secondaryHome');
|
||||||
const Demo = () => import('@/views/demo');
|
const Demo = () => import('@/views/demo');
|
||||||
const DemoTraining = () => import('@/views/newMap/displayNew/demoTraining');
|
const DemoTraining = () => import('@/views/newMap/displayNew/demoTraining');
|
||||||
|
const Test = () => import('@/views/test');
|
||||||
|
|
||||||
// import { GenerateRouteProjectList } from '@/scripts/ProjectConfig';
|
// import { GenerateRouteProjectList } from '@/scripts/ProjectConfig';
|
||||||
// import { getSessionStorage } from '@/utils/auth';
|
// import { getSessionStorage } from '@/utils/auth';
|
||||||
@ -207,6 +214,38 @@ export const userTrainingPlatform = '016'; // 实训系统
|
|||||||
// export const refereePlatform = '017'; // 裁判系统
|
// export const refereePlatform = '017'; // 裁判系统
|
||||||
|
|
||||||
export const constantRoutes = [
|
export const constantRoutes = [
|
||||||
|
{
|
||||||
|
path: '/test',
|
||||||
|
component: Test,
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/iscs_new/design/compose/edit',
|
||||||
|
hidden: true,
|
||||||
|
component: IscsNewDraw,
|
||||||
|
meta: {
|
||||||
|
i18n: 'router.iscsDraw',
|
||||||
|
roles: [admin]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/iscs_new/design/compose/preview',
|
||||||
|
hidden: true,
|
||||||
|
component: IscsNewPreview,
|
||||||
|
meta: {
|
||||||
|
i18n: 'router.iscsDraw',
|
||||||
|
roles: [admin]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/iscs_new/design/map/edit',
|
||||||
|
hidden: true,
|
||||||
|
component: IscsNewDesign,
|
||||||
|
meta: {
|
||||||
|
i18n: 'router.iscsDraw',
|
||||||
|
roles: [admin]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/demo',
|
path: '/demo',
|
||||||
component: Demo,
|
component: Demo,
|
||||||
@ -362,6 +401,11 @@ export const publicAsyncRoute = [
|
|||||||
component: DisplayNew,
|
component: DisplayNew,
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/displayCity/:mode',
|
||||||
|
component: DisplayCity,
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/design/displayNew/:mode',
|
path: '/design/displayNew/:mode',
|
||||||
component: DesignDisplayNew,
|
component: DesignDisplayNew,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
export function getBaseUrl() {
|
export function getBaseUrl() {
|
||||||
let BASE_API;
|
let BASE_API;
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
BASE_API = 'https://joylink.club/jlcloud';
|
// BASE_API = 'https://joylink.club/jlcloud';
|
||||||
// BASE_API = 'https://test.joylink.club/jlcloud';
|
BASE_API = 'https://test.joylink.club/jlcloud';
|
||||||
// BASE_API = 'http://192.168.8.107:9000'; // 袁琪
|
// BASE_API = 'http://192.168.8.107:9000'; // 袁琪
|
||||||
// BASE_API = 'http://192.168.8.129:9000'; // 旭强
|
// BASE_API = 'http://192.168.8.129:9000'; // 旭强
|
||||||
// BASE_API = 'http://192.168.8.119:9000'; // 张赛
|
// BASE_API = 'http://192.168.8.119:9000'; // 张赛
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { getBaseUrl } from '@/utils/baseUrl'
|
import { getBaseUrl } from '@/utils/baseUrl';
|
||||||
|
|
||||||
// 创建或者打开数据库
|
// 创建或者打开数据库
|
||||||
export function openIndexedDB() {
|
export function openIndexedDB() {
|
||||||
const baseUrl = getBaseUrl();
|
const baseUrl = getBaseUrl();
|
||||||
const indexedDBName = baseUrl.replace(/http.?:\/\/(.*)[\/|:].*/, "$1");
|
const indexedDBName = baseUrl.replace(/http.?:\/\/(.*)[\/|:].*/, '$1');
|
||||||
const request = window.indexedDB.open(indexedDBName, 1);
|
const request = window.indexedDB.open(indexedDBName, 1);
|
||||||
request.onerror = function (event) {
|
request.onerror = function (event) {
|
||||||
console.log('数据库打开报错');
|
console.log('数据库打开报错');
|
||||||
@ -18,6 +18,7 @@ export function openIndexedDB() {
|
|||||||
Vue.prototype.$db = event.target.result;
|
Vue.prototype.$db = event.target.result;
|
||||||
Vue.prototype.$db.createObjectStore('mapData', { keyPath: 'id' });
|
Vue.prototype.$db.createObjectStore('mapData', { keyPath: 'id' });
|
||||||
Vue.prototype.$db.createObjectStore('runPlan', { keyPath: 'templateId' });
|
Vue.prototype.$db.createObjectStore('runPlan', { keyPath: 'templateId' });
|
||||||
|
Vue.prototype.$db.createObjectStore('composeTemplateList', { keyPath: 'id' });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 新增数据
|
// 新增数据
|
||||||
|
@ -132,6 +132,8 @@ export default {
|
|||||||
{ name: '站厅D', value: 'bgStationD' },
|
{ name: '站厅D', value: 'bgStationD' },
|
||||||
{ name: '站厅E', value: 'bgStationE' },
|
{ name: '站厅E', value: 'bgStationE' },
|
||||||
{ name: '站厅F', value: 'bgStationF' },
|
{ name: '站厅F', value: 'bgStationF' },
|
||||||
|
{ name: '门禁站厅A', value: 'bgDoorStationA' },
|
||||||
|
{ name: '门禁站台A', value: 'bgDoorStandA' }
|
||||||
],
|
],
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
|
@ -233,10 +233,8 @@ export default {
|
|||||||
},
|
},
|
||||||
// 点击选择事件
|
// 点击选择事件
|
||||||
onSelected(em) {
|
onSelected(em) {
|
||||||
console.log(em);
|
|
||||||
},
|
},
|
||||||
onDblclick(em) {
|
onDblclick(em) {
|
||||||
console.log(em);
|
|
||||||
},
|
},
|
||||||
// 右键点击事件
|
// 右键点击事件
|
||||||
onContextMenu(em) {
|
onContextMenu(em) {
|
||||||
|
192
src/views/iscs_new/components/dataForm.vue
Normal file
192
src/views/iscs_new/components/dataForm.vue
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<template>
|
||||||
|
<el-form ref="form" :model="formModel" class="composeForm" label-width="110px">
|
||||||
|
<!-- name -->
|
||||||
|
<el-form-item prop="name" label="元素名称" class="formName" :rules="[ { required: true, message:'请输入名称', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
v-model="formModel.name"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
style="width:200px"
|
||||||
|
:maxlength="200"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-for="(styleGroup,index) in form.formGroup">
|
||||||
|
<div v-if="styleGroup.styleList.length>0" :key="index" class="styleGroup">
|
||||||
|
<div class="styleGroupName">
|
||||||
|
{{ styleGroup.name }}
|
||||||
|
</div>
|
||||||
|
<template v-for="item in styleGroup.styleList">
|
||||||
|
<el-form-item :key="item.prop" :prop="styleGroup.type+'.'+item.prop" :label="item.label" class="formName" :rules="item.rules?item.rules:[]">
|
||||||
|
<!-- {{ tempModel=styleGroup.type?formModel[styleGroup.type]:formModel }} -->
|
||||||
|
<el-tooltip
|
||||||
|
v-if="item.description"
|
||||||
|
:id="item.prop"
|
||||||
|
effect="dark"
|
||||||
|
:content="item.description"
|
||||||
|
:popper-options="{removeOnDestroy:true}"
|
||||||
|
placement="bottom-start"
|
||||||
|
popper-class="composeItemTooltip"
|
||||||
|
>
|
||||||
|
<span class="el-icon-info itemTips" />
|
||||||
|
</el-tooltip>
|
||||||
|
<template v-if="checkFieldType(item, 'Number')">
|
||||||
|
<el-input-number
|
||||||
|
v-if="item.precision!=undefined"
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
:precision="item.precision"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Boolean')">
|
||||||
|
<el-switch
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
style="vertical-align: top;"
|
||||||
|
size="small"
|
||||||
|
:active-color="item.activeColor || '#409eff'"
|
||||||
|
:inactive-color="item.inactiveColor || '#dcdfe6'"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Color')">
|
||||||
|
<el-color-picker
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
show-alpha
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'NumberArray')">
|
||||||
|
<el-input-number
|
||||||
|
v-for="count in item.length"
|
||||||
|
:key="count"
|
||||||
|
v-model="formModel[styleGroup.type][item.prop][count-1]"
|
||||||
|
style="margin:6px 0px 0px 5px"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
:precision="item.precision"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Points')">
|
||||||
|
<div class="point-section">
|
||||||
|
<template v-for="(point, j) in formModel[styleGroup.type][item.prop]">
|
||||||
|
<div :key="j" style="overflow: hidden;">
|
||||||
|
<el-input-number v-model="point[0]" size="mini" @blur="changeNumber(0,j,formModel[styleGroup.type],item.prop)" />
|
||||||
|
<span class="pointSplice">, </span>
|
||||||
|
<el-input-number v-model="point[1]" size="mini" @blur="changeNumber(1,j,formModel[styleGroup.type],item.prop)" />
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-plus"
|
||||||
|
circle
|
||||||
|
class="point-button"
|
||||||
|
@click="addPoint(j,formModel[styleGroup.type],item.prop)"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-minus"
|
||||||
|
:disabled="j <3"
|
||||||
|
circle
|
||||||
|
class="point-button"
|
||||||
|
style="margin-left: 4px;"
|
||||||
|
@click="delPoint(j,formModel[styleGroup.type],item.prop)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Select')">
|
||||||
|
<el-select
|
||||||
|
:ref="'select_'+item.prop"
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="option in item.optionList"
|
||||||
|
:key="option['value']"
|
||||||
|
:label="option['label']"
|
||||||
|
:value="option['value']"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'String')">
|
||||||
|
<el-input
|
||||||
|
v-model="formModel[styleGroup.type][item.prop]"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
style="width:200px"
|
||||||
|
:maxlength="item.maxlength"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name:'DataForm',
|
||||||
|
props: {
|
||||||
|
form: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
formModel: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkFieldType(field, type) {
|
||||||
|
return field.type === type;
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.$refs.form.resetFields();
|
||||||
|
},
|
||||||
|
changeNumber(type, index, form, prop) {
|
||||||
|
if (form[prop][index][type] == undefined || parseFloat(form[prop][index][type])) {
|
||||||
|
const newForm = Object.assign([], form[prop]);
|
||||||
|
newForm[index][type] = parseFloat(form[prop][index][type]) || 0;
|
||||||
|
this.$set(form, prop, newForm);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addPoint(index, form, prop) {
|
||||||
|
const data = [0, 0];
|
||||||
|
form[prop].splice(index + 1, 0, data);
|
||||||
|
},
|
||||||
|
delPoint(index, form, prop) {
|
||||||
|
form[prop].splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.composeForm{padding: 10px 15px;}
|
||||||
|
.styleGroup{border: 1px #ccc solid;padding:25px 20px 20px 20px;position: relative;margin-bottom: 30px;}
|
||||||
|
.formName .el-form-item__label {font-size:14px;}
|
||||||
|
.formName.el-form-item {margin-bottom:25px}
|
||||||
|
.point-section {float:left;display: inline-block;margin-top:8px}
|
||||||
|
.pointSplice{display: inline-block;margin-left: 4px;margin-right:4px;line-height: 28px;font-size:14px}
|
||||||
|
.styleGroupName{font-size: 14px;position: absolute;max-width: 100px;height: 20px;background: #fff;left: 10px;top: -9px;text-align: center;padding: 0px 10px;}
|
||||||
|
.point-button {width:28px;height:28px;display:inline-block;margin-left:5px;text-align:center;padding:0px;}
|
||||||
|
.itemTips{display: inline-block;font-size: 18px;vertical-align: top;margin-left: -8px;margin-right: 5px;cursor: pointer;color: #dde0e3;}
|
||||||
|
// align-items: center;justify-content: center;
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.composeForm .el-form-item__label{line-height:20px;margin-top: 20px;transform: translateY(-50%);}
|
||||||
|
.composeForm .el-form-item__content{font-size: 0px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align: center;-ms-flex-align: center;align-items: center;min-height: 40px;flex-wrap: wrap;justify-content: flex-start;}
|
||||||
|
.composeItemTooltip{max-width:300px}
|
||||||
|
</style>
|
163
src/views/iscs_new/components/eachFormItem.vue
Normal file
163
src/views/iscs_new/components/eachFormItem.vue
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<el-form-item :label="item.label" class="formName" :rules="item.rules?item.rules:[]" :prop="parentProp+'.'+item.prop">
|
||||||
|
<!-- :prop="styleGroup.type+'.'+item.prop" -->
|
||||||
|
<template v-if="checkFieldType(item, 'Number')">
|
||||||
|
<el-input-number
|
||||||
|
v-if="item.precision!=undefined"
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
:precision="item.precision"
|
||||||
|
/>
|
||||||
|
<el-input-number
|
||||||
|
v-else
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Boolean')">
|
||||||
|
<el-switch
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
style="vertical-align: top;"
|
||||||
|
size="small"
|
||||||
|
:active-color="item.activeColor || '#409eff'"
|
||||||
|
:inactive-color="item.inactiveColor || '#dcdfe6'"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'Color')">
|
||||||
|
<el-color-picker
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
show-alpha
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'NumberArray')">
|
||||||
|
<el-input-number
|
||||||
|
v-for="count in item.length"
|
||||||
|
:key="parentProp+'.'+item.prop+''+count"
|
||||||
|
v-model="data[item.prop][count-1]"
|
||||||
|
style="margin:6px 0px 0px 5px"
|
||||||
|
size="small"
|
||||||
|
:min="isNaN(item.min) ? -Infinity : item.min"
|
||||||
|
:max="isNaN(item.max)? Infinity : item.max"
|
||||||
|
:step="isNaN(item.step) ? -Infinity : item.step"
|
||||||
|
:precision="item.precision"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- <template v-else-if="checkFieldType(item, 'Points')">
|
||||||
|
<div class="point-section">
|
||||||
|
<template v-for="(point, j) in formModel[styleGroup.type][item.prop]">
|
||||||
|
<div :key="j" style="overflow: hidden;">
|
||||||
|
<el-input-number v-model="point[0]" size="mini" @blur="changeNumber(0,j,formModel[styleGroup.type],item.prop)" />
|
||||||
|
<span class="pointSplice">, </span>
|
||||||
|
<el-input-number v-model="point[1]" size="mini" @blur="changeNumber(1,j,formModel[styleGroup.type],item.prop)" />
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-plus"
|
||||||
|
circle
|
||||||
|
class="point-button"
|
||||||
|
@click="addPoint(j,formModel[styleGroup.type],item.prop)"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-minus"
|
||||||
|
:disabled="j <3"
|
||||||
|
circle
|
||||||
|
class="point-button"
|
||||||
|
style="margin-left: 4px;"
|
||||||
|
@click="delPoint(j,formModel[styleGroup.type],item.prop)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template> -->
|
||||||
|
<template v-else-if="checkFieldType(item, 'Select')">
|
||||||
|
<el-select
|
||||||
|
:ref="'select_'+item.prop"
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="option in item.optionList"
|
||||||
|
:key="option['value']"
|
||||||
|
:label="option['label']"
|
||||||
|
:value="option['value']"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="checkFieldType(item, 'String')">
|
||||||
|
<el-input
|
||||||
|
v-model="data[item.prop]"
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
style="width:200px"
|
||||||
|
:maxlength="item.maxlength"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<span class="el-icon-error deleteCurrent" @click="deleteCurrent(item.prop)" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import elementConst from '@/iscs_new/core/form/elementConst';
|
||||||
|
export default {
|
||||||
|
name:'EachFormItem',
|
||||||
|
props: {
|
||||||
|
prop: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
type:{
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
styleType: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
parentProp:{
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
item:{label:'', type:'' }
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const list = elementConst[this.type]['formList'][this.styleType];
|
||||||
|
const data = list.find(each=>{ return each.prop == this.prop; });
|
||||||
|
if (data) {
|
||||||
|
this.item = data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
checkFieldType(field, type) {
|
||||||
|
return field.type === type;
|
||||||
|
},
|
||||||
|
deleteCurrent(prop) {
|
||||||
|
this.$emit('deleteShape', {styleType:this.styleType, data:this.data, prop:prop});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.deleteCurrent{
|
||||||
|
font-size: 20px;
|
||||||
|
color: #f00;
|
||||||
|
margin-left: 15px;
|
||||||
|
vertical-align: top;
|
||||||
|
display: inline-flex;
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
225
src/views/iscs_new/components/tableForm.vue
Normal file
225
src/views/iscs_new/components/tableForm.vue
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="small" class="addStatus" @click="addStatus">添加</el-button>
|
||||||
|
<el-form ref="form" class="tableForm" :model="formModel">
|
||||||
|
<!-- label-width="110px" -->
|
||||||
|
<el-table
|
||||||
|
:data="formModel.stateList"
|
||||||
|
stripe
|
||||||
|
class="eachStatusTable"
|
||||||
|
size="mini"
|
||||||
|
row-key="id"
|
||||||
|
:expand-row-keys="expandKeys"
|
||||||
|
@expand-change="expandChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="expand">
|
||||||
|
<template slot-scope="props">
|
||||||
|
<div class="styleList">
|
||||||
|
<div class="styleListName">样式</div>
|
||||||
|
<div class="addStyleForm">
|
||||||
|
<el-select v-model="props.row.defaultStyleSelect" size="mini">
|
||||||
|
<el-option v-for="(eachStyle) in styleSelectList" :key="eachStyle.value" :label="eachStyle.label" :value="eachStyle.value" />
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" size="mini" class="addStyle" @click="addStyle(props.$index,'style')">添加</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="props.row.style" class="styleInList">
|
||||||
|
<div v-for="(eachStyleInfo,index) in Object.keys(props.row.style)" :key="index" class="eachStyleInfo">
|
||||||
|
<each-form-item
|
||||||
|
:prop="eachStyleInfo"
|
||||||
|
:data="formModel.stateList[props.$index].style"
|
||||||
|
:type="formModel.type"
|
||||||
|
style-type="style"
|
||||||
|
:parent-prop="'stateList.'+props.$index+'.style'"
|
||||||
|
@deleteShape="deleteShape"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shapeList">
|
||||||
|
<div class="shapeListName">绘图</div>
|
||||||
|
<div class="addStyleForm">
|
||||||
|
<el-select v-model="props.row.defaultShapeSelect" size="mini">
|
||||||
|
<el-option v-for="(eachShape) in shapeSelectList" :key="eachShape.value" :label="eachShape.label" :value="eachShape.value" />
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" size="mini" class="addStyle" @click="addStyle(props.$index,'shape')">添加</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="props.row.shape" class="styleInList">
|
||||||
|
<div v-for="(eachShapeInfo,index) in Object.keys(props.row.shape)" :key="index" class="eachStyleInfo">
|
||||||
|
<each-form-item
|
||||||
|
:prop="eachShapeInfo"
|
||||||
|
:data="formModel.stateList[props.$index].shape"
|
||||||
|
:type="formModel.type"
|
||||||
|
style-type="shape"
|
||||||
|
:parent-prop="'stateList.'+props.$index+'.shape'"
|
||||||
|
@deleteShape="deleteShape"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" width="178">
|
||||||
|
<!-- align="center" -->
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.status'"
|
||||||
|
:rules="[{required: true, message:'请输入状态', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.status" size="mini" type="text" style="width:158px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="描述" width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.description'"
|
||||||
|
:rules="[{required: true, message:'请输入描述', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.description" size="mini" type="text" style="width:170px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="danger" size="mini" @click="deleteStatus(scope.$index,scope.row)">删除</el-button>
|
||||||
|
<!-- <el-button type="success" size="mini" @click="previewStatus(scope.$index,scope.row)">预览</el-button> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- :model="formModel" -->
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import elementConst from '@/iscs_new/core/form/elementConst';
|
||||||
|
import EachFormItem from './eachFormItem';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name:'TableForm',
|
||||||
|
components:{
|
||||||
|
EachFormItem
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
composeElem: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
formModel:this.composeElem,
|
||||||
|
// {stateList:this.composeElem.stateList, style:this.composeElem.style, type:this.composeElem.type, shape:this.composeElem.shape}
|
||||||
|
styleSelectList:[],
|
||||||
|
shapeSelectList:[],
|
||||||
|
expandKeys:[]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const styleNameList = Object.keys(this.formModel.style);
|
||||||
|
const style = elementConst[this.formModel.type]['formList']['style'];
|
||||||
|
styleNameList.forEach(eachStyleName=>{
|
||||||
|
const eachStyle = style.find(each=>{ return each.prop == eachStyleName; });
|
||||||
|
this.styleSelectList.push({value:eachStyleName, label:eachStyle.label});
|
||||||
|
});
|
||||||
|
|
||||||
|
const shapeNameList = Object.keys(this.formModel.shape);
|
||||||
|
const shape = elementConst[this.formModel.type]['formList']['shape'];
|
||||||
|
shapeNameList.forEach(eachShapeName=>{
|
||||||
|
const eachShape = shape.find(each=>{ return each.prop == eachShapeName; });
|
||||||
|
this.shapeSelectList.push({value:eachShapeName, label:eachShape.label});
|
||||||
|
});
|
||||||
|
this.formModel.stateList.forEach(each=>{
|
||||||
|
each.defaultStyleSelect = this.styleSelectList[0].value;
|
||||||
|
each.defaultShapeSelect = this.shapeSelectList[0].value;
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
addStatus() {
|
||||||
|
const length = this.formModel.stateList.length;
|
||||||
|
this.formModel.stateList.push({id:length + 1, status:'', description:'', defaultStyleSelect:this.styleSelectList[0].value,
|
||||||
|
defaultShapeSelect:this.shapeSelectList[0].value});
|
||||||
|
this.expandKeys.push(length + 1);
|
||||||
|
},
|
||||||
|
deleteStatus(index, row) {
|
||||||
|
this.formModel.stateList.splice(index, 1);
|
||||||
|
const key = this.expandKeys.findIndex(each=>{ return each == row.id; });
|
||||||
|
if (key > 0) { this.expandKeys.splice(key, 1); }
|
||||||
|
},
|
||||||
|
// previewStatus(index, row) {
|
||||||
|
// const styleLength = Object.keys(row.style || {}).length;
|
||||||
|
// const shapeLength = Object.keys(row.shape || {}).length;
|
||||||
|
// if (styleLength > 0 || shapeLength > 0 ) {
|
||||||
|
// const data = {style:row.style || {}, shape:row.shape || {}};
|
||||||
|
// debugger;
|
||||||
|
// // this.$iscs
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
addStyle(index, type) {
|
||||||
|
const style = this.formModel.stateList[index][type];
|
||||||
|
if (!style) {
|
||||||
|
this.$set(this.formModel.stateList[index], type, {});
|
||||||
|
}
|
||||||
|
const data = this.formModel.stateList[index];
|
||||||
|
const dataName = 'default' + type.replace(type[0], type[0].toUpperCase()) + 'Select';
|
||||||
|
if (!data[type][data[dataName]] && data[dataName]) {
|
||||||
|
const other = utils.deepClone(this.formModel[type][data[dataName]]);
|
||||||
|
this.$set(this.formModel.stateList[index][type], data[dataName], other);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expandChange(row, expandedRows) {
|
||||||
|
this.expandKeys = [];
|
||||||
|
expandedRows.forEach(each=>{
|
||||||
|
this.expandKeys.push(each.id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteShape({styleType, data, prop}) {
|
||||||
|
this.$delete(data, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.eachStatusTable{
|
||||||
|
width: 530px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
border: 1px #dedede solid;
|
||||||
|
}
|
||||||
|
.addStatus{
|
||||||
|
float: right;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.styleList,.shapeList{
|
||||||
|
padding: 15px 10px;
|
||||||
|
border: 1px #ccc solid;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom:20px;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.styleListName,.shapeListName{
|
||||||
|
font-size: 14px;
|
||||||
|
position: absolute;
|
||||||
|
left: 6px;
|
||||||
|
top: -8px;
|
||||||
|
width: 40px;
|
||||||
|
background: #fff;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.addStyle,.addShape{
|
||||||
|
float: right;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.styleInList{
|
||||||
|
margin-top: 15px;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
// .eachStyleInfo .el-form-item{border-bottom: 1px #dedede solid;}
|
||||||
|
</style>
|
||||||
|
<style lang="sass">
|
||||||
|
.eachStatusTable .el-table__expanded-cell{padding: 20px;}
|
||||||
|
</style>
|
323
src/views/iscs_new/iscsDesign/index.vue
Normal file
323
src/views/iscs_new/iscsDesign/index.vue
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-center">
|
||||||
|
<div class="mapPaint">
|
||||||
|
<div class="map-view">
|
||||||
|
<iscs-canvas ref="iscsCanvas" @selected="onSelected" />
|
||||||
|
</div>
|
||||||
|
<div class="right-card" :class="{'hide': draftShow}">
|
||||||
|
<div class="btn_draft_box" @click="draftShow = !draftShow"><i :class="draftShow?'el-icon-arrow-right':'el-icon-arrow-left'" /></div>
|
||||||
|
<el-card type="border-card" class="heightClass">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
style="float: right; padding: 3px 0; margin-right: 5px;"
|
||||||
|
@click="onSave"
|
||||||
|
>保存</el-button>
|
||||||
|
</div>
|
||||||
|
<el-tabs id="cardTab" v-model="cardTab" class="card" type="border-card" @tab-click="onSelectCardTab">
|
||||||
|
<el-tab-pane label="元素绘制" name="first">
|
||||||
|
<el-tabs v-model="enabledTab" class="card" type="card" @tab-click="onSelectTab">
|
||||||
|
<el-tab-pane v-for="(element,index) in elementList" :key="index" :label="element.name" :name="element.type" :lazy="true">
|
||||||
|
<data-form :ref="'dataform'+element.type" :form="element" :form-model="element.model" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button v-show="!selected" type="primary" size="small" @click="onSubmit">添加</el-button>
|
||||||
|
<el-button v-show="selected" type="warning" size="small" @click="onModify">修改</el-button>
|
||||||
|
<el-button v-show="selected" type="danger" size="small" @click="onDelete">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="状态编辑" name="second">
|
||||||
|
<el-tabs v-model="statusTab" class="card" type="card" @tab-click="onSelectTab">
|
||||||
|
<el-tab-pane v-for="(composeElem,index) in composeElemList" :key="index" :label="composeElem.name" :name="composeElem.code" :lazy="true">
|
||||||
|
<table-form :ref="'tableform'+composeElem.code" :state-list="composeElem.stateList" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import localStore from 'storejs';
|
||||||
|
import iscsCanvas from './iscsCanvas';
|
||||||
|
import formBuilder from '@/iscs_new/core/form/formBuilder';
|
||||||
|
import DataForm from '../components/dataForm';
|
||||||
|
import TableForm from '../components/tableForm';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IscsView',
|
||||||
|
components: {
|
||||||
|
iscsCanvas,
|
||||||
|
DataForm,
|
||||||
|
TableForm
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
size: {
|
||||||
|
width: this.$store.state.app.width - 521,
|
||||||
|
height: this.$store.state.app.height - 60
|
||||||
|
},
|
||||||
|
widthLeft: Number(localStore.get('LeftWidth')) || 450,
|
||||||
|
draftShow: false,
|
||||||
|
selected: null,
|
||||||
|
enabledTab:'',
|
||||||
|
cardTab:'first',
|
||||||
|
statusTab:'',
|
||||||
|
showDeleteButton:false,
|
||||||
|
elementList:[],
|
||||||
|
composeElemList:[]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
iscsMode() {
|
||||||
|
return this.$route.query.mode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(val) {
|
||||||
|
this.onIscsChange(this.$route.query.mode, this.$route.query.system, this.$route.query.part);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.composeName = this.$route.query.composeName;
|
||||||
|
this.elementList = formBuilder.buildFormList();
|
||||||
|
this.enabledTab = this.elementList[0].type;
|
||||||
|
this.getComposeElemList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onIscsChange(mode, system, part) {
|
||||||
|
// this.$refs.iscsPlate.show(mode, system, part);
|
||||||
|
// this.$refs.iscsPlate.drawIscsInit();
|
||||||
|
},
|
||||||
|
onSave() {
|
||||||
|
const id = this.$route.query.id;
|
||||||
|
const name = this.$route.query.name||"<模型名称>";
|
||||||
|
const type = this.$route.query.type||"<模型类型>";
|
||||||
|
const source = this.$iscs.getSource();
|
||||||
|
if (id && source) {
|
||||||
|
const elementList = source.elementList.map(el => {
|
||||||
|
return this.$iscs.getShapeByCode(el.code).model;
|
||||||
|
});
|
||||||
|
const composeList = source.composeList.map(el => {
|
||||||
|
return this.$iscs.getShapeByCode(el.code).model;
|
||||||
|
});
|
||||||
|
const rect = elementList.reduce((temp,el) => {
|
||||||
|
const shape = this.$iscs.getShapeByCode(el.code);
|
||||||
|
return shape&&temp? temp.union(shape.getBoundingRect().clone()): shape.getBoundingRect()
|
||||||
|
}, null);
|
||||||
|
const position = rect? [(rect.x + rect.width)/2, (rect.y + rect.height)/2]: [0,0];
|
||||||
|
const model = { id, name, type, elementList, composeList, position };
|
||||||
|
Idb.delete('composeList', model.id);
|
||||||
|
Idb.write('composeList', model);
|
||||||
|
Idb.list('composeList').then(list => {
|
||||||
|
console.log(list)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectTab() {
|
||||||
|
this.selected = null;
|
||||||
|
},
|
||||||
|
onSelectCardTab() {
|
||||||
|
|
||||||
|
},
|
||||||
|
onSelected(em) {
|
||||||
|
if (em.model) {
|
||||||
|
this.selected = JSON.parse(JSON.stringify(em.model));
|
||||||
|
const elem = this.elementList.find(el => el.type == this.selected.type);
|
||||||
|
if (elem) {
|
||||||
|
elem.model = this.selected;
|
||||||
|
this.enabledTab = this.selected.type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selected = null;
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const formModel = this.$refs['dataform' + this.enabledTab][0].formModel;
|
||||||
|
const newModel = utils.deepClone(formModel);
|
||||||
|
newModel.code = utils.getUID(this.enabledTab);
|
||||||
|
newModel.type = this.enabledTab;
|
||||||
|
newModel.name = '<名称>';
|
||||||
|
newModel.stateList = [];
|
||||||
|
this.$refs.iscsCanvas.doAction([{model: newModel, action: {shapeType: shapeType.Element, order: orders.Add}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
this.getComposeElemList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onModify() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const model = utils.deepClone(this.$refs['dataform' + this.enabledTab][0].formModel);
|
||||||
|
model.code = this.selected.code;
|
||||||
|
model.type = this.selected.type;
|
||||||
|
model.name = this.selected.name;
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Update}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const model = utils.deepClone(this.$refs['dataform' + this.enabledTab][0].formModel);
|
||||||
|
model.code = this.selected.code;
|
||||||
|
model.type = this.selected.type;
|
||||||
|
model.name = this.selected.name;
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Delete}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
this.getComposeElemList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clear(enabledTab) {
|
||||||
|
this.$refs['dataform' + enabledTab][0].init();
|
||||||
|
this.selected = null;
|
||||||
|
},
|
||||||
|
getComposeElemList() {
|
||||||
|
const source = this.$iscs.getSource();
|
||||||
|
if (source &&
|
||||||
|
source.elementList &&
|
||||||
|
source.elementList.length) {
|
||||||
|
this.composeElemList = source.elementList;
|
||||||
|
this.statusTab = this.composeElemList[0].code;
|
||||||
|
} else {
|
||||||
|
this.composeElemList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
@import "src/styles/mixin.scss";
|
||||||
|
.card{
|
||||||
|
height: 100%;
|
||||||
|
display:flex;width: 100%;flex-direction: column
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .el-tab-pane{
|
||||||
|
flex:1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding-bottom:30px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
// height: 110px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FFFFFF;;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
border-radius: 5px;
|
||||||
|
// box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
background: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-view {
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.heightClass{height:100%;overflow:hidden;display:flex;width: 100%;flex-direction: column;}
|
||||||
|
|
||||||
|
.mapPaint{
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
width:100%;
|
||||||
|
position:absolute;
|
||||||
|
left:0;top:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-card{
|
||||||
|
width: 550px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
transform: translateX(550px);
|
||||||
|
transition: all 0.5s;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 9;
|
||||||
|
/deep/{
|
||||||
|
.v-modal{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.hide{
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_draft_box{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
padding: 8px 3px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
|
transform: translateX(-22px);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
box-shadow: -2px 0px 2px #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_table_box {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: calc(50% + 50px);
|
||||||
|
padding: 8px 3px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
|
transform: translateX(-22px);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
box-shadow: -2px 0px 2px #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottomBtnGroup{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 43px;
|
||||||
|
text-align: right;
|
||||||
|
right: 0px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 2;
|
||||||
|
padding-top: 5px;
|
||||||
|
border-bottom: 1px #dedede solid;
|
||||||
|
box-shadow: 2px -3px 5px #dedede;
|
||||||
|
}
|
||||||
|
.bottomBtnGroup button{
|
||||||
|
display: inline-block;
|
||||||
|
margin-right:10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.heightClass .el-card__body{
|
||||||
|
flex:1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#cardTab .el-tabs__content{
|
||||||
|
padding:0px;
|
||||||
|
}
|
||||||
|
</style>
|
183
src/views/iscs_new/iscsDesign/iscsCanvas.vue
Normal file
183
src/views/iscs_new/iscsDesign/iscsCanvas.vue
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div :id="iscsId" v-loading="loading" :style="{ width: width +'px', height: height +'px',background:'#425a74' }" class="iscs-canvas" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Iscs from '@/iscs_new/map';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
import ShapeBuilder from '@/iscs_new/plugins/shapeBuilder';
|
||||||
|
import ShapeProperty from '@/iscs_new/plugins/shapeProperty';
|
||||||
|
import ShapeContextMenu from '@/iscs_new/plugins/shapeContextMenu';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataZoom: {
|
||||||
|
offsetX: '0',
|
||||||
|
offsetY: '0',
|
||||||
|
scaleRate: '1'
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
scaleRate: '1',
|
||||||
|
origin: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('iscs', [
|
||||||
|
'iscs'
|
||||||
|
]),
|
||||||
|
iscsId() {
|
||||||
|
return ['iscs', (Math.random().toFixed(5)) * 100000].join('_');
|
||||||
|
},
|
||||||
|
width() {
|
||||||
|
return document.documentElement.clientWidth;
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
return document.documentElement.clientHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.config.canvasSizeCount': function (val) {
|
||||||
|
this.resize();
|
||||||
|
},
|
||||||
|
'$store.state.socket.equipmentStatus': function (val) {
|
||||||
|
if (val.length) {
|
||||||
|
this.stateMessage(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化窗口
|
||||||
|
init() {
|
||||||
|
document.getElementById(this.iscsId).oncontextmenu = function (e) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$iscs = new Iscs({
|
||||||
|
dom: document.getElementById(this.iscsId),
|
||||||
|
draw: true,
|
||||||
|
config: {
|
||||||
|
renderer: 'canvas',
|
||||||
|
width: this.width,
|
||||||
|
height: this.height
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scaleRate: 1,
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 0
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
ShapeBuilder,
|
||||||
|
// ShapeProperty,
|
||||||
|
ShapeContextMenu
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
panEnable: true,
|
||||||
|
zoomEnable: true,
|
||||||
|
keyEnable: true,
|
||||||
|
draggle: true,
|
||||||
|
selecting: true,
|
||||||
|
selectable: true,
|
||||||
|
reflect: true
|
||||||
|
}
|
||||||
|
if (this.$route.query.id) {
|
||||||
|
setTimeout(_ => {
|
||||||
|
Idb.select('composeList', this.$route.query.id).then(resp => {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: resp.elementList||[],
|
||||||
|
composeList: resp.composeList||[]
|
||||||
|
}, option);
|
||||||
|
}).catch(error => {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
})
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$iscs = this.$iscs;
|
||||||
|
this.$iscs.on('viewLoaded', this.onViewLoaded, this);
|
||||||
|
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||||
|
this.$iscs.on('click', this.onClick, this);
|
||||||
|
this.$iscs.on('reflect', this.onReflect, this);
|
||||||
|
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||||
|
window.document.oncontextmenu = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 视图加载完成
|
||||||
|
onViewLoaded(e) {
|
||||||
|
},
|
||||||
|
// 键盘快捷键事件
|
||||||
|
onKeyboard(hook) {
|
||||||
|
console.log(hook);
|
||||||
|
},
|
||||||
|
// 点击选择事件
|
||||||
|
onClick(em={}) {
|
||||||
|
this.$emit('selected', em);
|
||||||
|
},
|
||||||
|
onReflect(em={}) {
|
||||||
|
this.$emit('selected', this.$iscs.getShapeByCode(em.code));
|
||||||
|
},
|
||||||
|
// 右键点击事件
|
||||||
|
onContextMenu(em={}) {
|
||||||
|
this.$emit('contextMenu', em.model);
|
||||||
|
},
|
||||||
|
// 执行操作
|
||||||
|
doAction(list) {
|
||||||
|
this.$iscs && this.$iscs.render(list);
|
||||||
|
},
|
||||||
|
// 消息处理
|
||||||
|
stateMessage(val) {
|
||||||
|
this.$iscs && this.$iscs.setDeviceStatus(val);
|
||||||
|
},
|
||||||
|
// 充值窗口大小
|
||||||
|
resize() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$iscs && this.$iscs.resize({ width: this.width, height: this.height });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 销毁
|
||||||
|
destroy() {
|
||||||
|
if (this.$iscs) {
|
||||||
|
this.$iscs.destroy();
|
||||||
|
this.$iscs = null;
|
||||||
|
Vue.prototype.$iscs = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.iscs-button{
|
||||||
|
position: absolute;
|
||||||
|
float: right;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 15px;
|
||||||
|
}
|
||||||
|
.iscs-canvas{
|
||||||
|
}
|
||||||
|
</style>
|
386
src/views/iscs_new/iscsDraw/index.vue
Normal file
386
src/views/iscs_new/iscsDraw/index.vue
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-center">
|
||||||
|
<div class="mapPaint">
|
||||||
|
<div class="map-view">
|
||||||
|
<iscs-canvas ref="iscsCanvas" @selected="onSelected" @setStateList="setStateList" />
|
||||||
|
</div>
|
||||||
|
<div class="right-card" :class="{'hide': draftShow}">
|
||||||
|
<div class="btn_draft_box" @click="draftShow = !draftShow"><i :class="draftShow?'el-icon-arrow-right':'el-icon-arrow-left'" /></div>
|
||||||
|
<el-card type="border-card" class="heightClass">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
style="float: right; padding: 3px 0; margin-right: 5px;"
|
||||||
|
@click="onSave"
|
||||||
|
>保存</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if=" composeElemList.length>0"
|
||||||
|
type="text"
|
||||||
|
style="float: right; padding: 3px 0; margin-right: 5px;"
|
||||||
|
@click="onPreview"
|
||||||
|
>预览</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if=" composeElemList.length>0"
|
||||||
|
type="text"
|
||||||
|
style="float: right; padding: 3px 0; margin-right: 5px;"
|
||||||
|
@click="onModifyStatus"
|
||||||
|
>状态编辑</el-button>
|
||||||
|
</div>
|
||||||
|
<el-tabs id="cardTab" v-model="cardTab" class="card" type="border-card" @tab-click="onSelectCardTab">
|
||||||
|
<el-tab-pane label="元素绘制" name="first">
|
||||||
|
<el-tabs v-model="enabledTab" class="card" type="card" @tab-click="onSelectTab">
|
||||||
|
<el-tab-pane v-for="(element,index) in elementList" :key="index" :label="element.name" :name="element.type" :lazy="true">
|
||||||
|
<data-form :ref="'dataform'+element.type" :form="element" :form-model="element.model" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button v-show="!selected" type="primary" size="small" @click="onSubmit">添加</el-button>
|
||||||
|
<el-button v-show="selected" type="warning" size="small" @click="onModify">修改</el-button>
|
||||||
|
<el-button v-show="selected" type="danger" size="small" @click="onDelete">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="单元素状态编辑" name="second">
|
||||||
|
<el-tabs v-model="statusTab" class="card" type="card" @tab-click="onSelectTab">
|
||||||
|
<el-tab-pane v-for="(composeElem,index) in composeElemList" :key="index" :label="composeElem.name" :name="composeElem.code" :lazy="true">
|
||||||
|
<table-form :ref="'tableform'+composeElem.code" :compose-elem="composeElem" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button type="primary" size="small" @click="onSaveStatus">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<!-- <el-tab-pane label="状态编辑" name="third">
|
||||||
|
<status-combine-edit ref="editStatusForm" :state-list="stateList" @saveStateList="saveStateList" />
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button type="primary" size="small" @click="onEditStatusSave">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane> -->
|
||||||
|
</el-tabs>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<status-list ref="statusList" @setStateList="setStateList" />
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import localStore from 'storejs';
|
||||||
|
import iscsCanvas from './iscsCanvas';
|
||||||
|
import formBuilder from '@/iscs_new/core/form/formBuilder';
|
||||||
|
import DataForm from '../components/dataForm';
|
||||||
|
import TableForm from '../components/tableForm';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
// import StatusCombineEdit from './statusCombineEdit';
|
||||||
|
import StatusList from './statusList';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IscsView',
|
||||||
|
components: {
|
||||||
|
iscsCanvas,
|
||||||
|
DataForm,
|
||||||
|
TableForm,
|
||||||
|
StatusList
|
||||||
|
// StatusCombineEdit
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
size: {
|
||||||
|
width: this.$store.state.app.width - 521,
|
||||||
|
height: this.$store.state.app.height - 60
|
||||||
|
},
|
||||||
|
widthLeft: Number(localStore.get('LeftWidth')) || 450,
|
||||||
|
draftShow: false,
|
||||||
|
selected: null,
|
||||||
|
enabledTab:'',
|
||||||
|
cardTab:'first',
|
||||||
|
statusTab:'',
|
||||||
|
showDeleteButton:false,
|
||||||
|
elementList:[],
|
||||||
|
composeElemList:[],
|
||||||
|
stateList:[]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
iscsMode() {
|
||||||
|
return this.$route.query.mode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(val) {
|
||||||
|
this.onIscsChange(this.$route.query.mode, this.$route.query.system, this.$route.query.part);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.composeName = this.$route.query.composeName;
|
||||||
|
this.elementList = formBuilder.buildFormList();
|
||||||
|
this.enabledTab = this.elementList[0].type;
|
||||||
|
this.getComposeElemList();
|
||||||
|
EventBus.$on('getComposeElemList', () => {
|
||||||
|
this.getComposeElemList();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onIscsChange(mode, system, part) {
|
||||||
|
// this.$refs.iscsPlate.show(mode, system, part);
|
||||||
|
// this.$refs.iscsPlate.drawIscsInit();
|
||||||
|
},
|
||||||
|
onSave() {
|
||||||
|
const id = this.$route.query.id;
|
||||||
|
const name = this.$route.query.name || '<模型名称>';
|
||||||
|
const type = this.$route.query.type || '<模型类型>';
|
||||||
|
const source = this.$iscs.getSource();
|
||||||
|
if (id && source) {
|
||||||
|
const shapeList = source.elementList;
|
||||||
|
shapeList.forEach(el => {
|
||||||
|
return this.$iscs.getShapeByCode(el.code).model;
|
||||||
|
});
|
||||||
|
// const composeList = source.composeList.map(el => {
|
||||||
|
// return this.$iscs.getShapeByCode(el.code).model;
|
||||||
|
// });
|
||||||
|
// const rect = shapeList.reduce((temp, el) => {
|
||||||
|
// const shape = this.$iscs.getShapeByCode(el.code);
|
||||||
|
// return shape && temp ? temp.union(shape.getBoundingRect().clone()) : shape.getBoundingRect();
|
||||||
|
// }, null);
|
||||||
|
// const position = rect ? [(rect.x + rect.width) / 2, (rect.y + rect.height) / 2] : [0, 0];
|
||||||
|
const position = [0, 0];
|
||||||
|
const stateList = this.stateList;
|
||||||
|
const model = { id, name, type, shapeList, stateList, position };
|
||||||
|
|
||||||
|
Idb.delete('composeTemplateList', model.id);
|
||||||
|
Idb.write('composeTemplateList', model);
|
||||||
|
Idb.list('composeTemplateList').then(list => {
|
||||||
|
console.log(list);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectTab() {
|
||||||
|
this.selected = null;
|
||||||
|
},
|
||||||
|
onSelectCardTab() {
|
||||||
|
|
||||||
|
},
|
||||||
|
setStateList(stateList) {
|
||||||
|
this.stateList = stateList;
|
||||||
|
},
|
||||||
|
onSelected(em) {
|
||||||
|
if (em.model) {
|
||||||
|
this.selected = JSON.parse(JSON.stringify(em.model));
|
||||||
|
const elem = this.elementList.find(el => el.type == this.selected.type);
|
||||||
|
if (elem) {
|
||||||
|
elem.model = this.selected;
|
||||||
|
this.enabledTab = this.selected.type;
|
||||||
|
this.cardTab = 'first';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selected = null;
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const formModel = this.$refs['dataform' + this.enabledTab][0].formModel;
|
||||||
|
const newModel = utils.deepClone(formModel);
|
||||||
|
newModel.code = utils.getUID(this.enabledTab);
|
||||||
|
newModel.type = this.enabledTab;
|
||||||
|
newModel.name = '<名称>';
|
||||||
|
newModel.stateList = [];
|
||||||
|
this.$refs.iscsCanvas.doAction([{model: newModel, action: {shapeType: shapeType.Element, order: orders.Add}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
this.getComposeElemList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onModify() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const model = utils.deepClone(this.$refs['dataform' + this.enabledTab][0].formModel);
|
||||||
|
model.code = this.selected.code;
|
||||||
|
model.type = this.selected.type;
|
||||||
|
model.name = this.selected.name;
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Update}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onDelete() {
|
||||||
|
this.$refs['dataform' + this.enabledTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const model = utils.deepClone(this.$refs['dataform' + this.enabledTab][0].formModel);
|
||||||
|
model.code = this.selected.code;
|
||||||
|
model.type = this.selected.type;
|
||||||
|
model.name = this.selected.name;
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Delete}}]);
|
||||||
|
this.clear(this.enabledTab);
|
||||||
|
this.getComposeElemList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clear(enabledTab) {
|
||||||
|
this.$refs['dataform' + enabledTab][0].init();
|
||||||
|
this.selected = null;
|
||||||
|
},
|
||||||
|
getComposeElemList() {
|
||||||
|
const source = this.$iscs.getSource();
|
||||||
|
if (source &&
|
||||||
|
source.elementList &&
|
||||||
|
source.elementList.length) {
|
||||||
|
this.composeElemList = source.elementList;
|
||||||
|
this.statusTab = this.composeElemList[0].code;
|
||||||
|
} else {
|
||||||
|
this.composeElemList = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSaveStatus() {
|
||||||
|
this.$refs['tableform' + this.statusTab][0].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const model = utils.deepClone(this.$refs['tableform' + this.statusTab][0].formModel);
|
||||||
|
model.stateList.map(state=>{ delete state.defaultStyleSelect; delete state.defaultShapeSelect; });
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Update}}]);
|
||||||
|
this.onSave();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onEditStatusSave() {
|
||||||
|
this.$refs['editStatusForm'].$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.onSave();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPreview() {
|
||||||
|
this.$router.push({ path: `/iscs_new/design/compose/preview`, query:{id:this.$route.query.id} });
|
||||||
|
},
|
||||||
|
|
||||||
|
onModifyStatus() {
|
||||||
|
this.$refs.statusList.doShow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
@import "src/styles/mixin.scss";
|
||||||
|
.card{
|
||||||
|
height: 100%;
|
||||||
|
display:flex;width: 100%;flex-direction: column
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .el-tab-pane{
|
||||||
|
flex:1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
padding-bottom:30px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
// height: 110px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FFFFFF;;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
border-radius: 5px;
|
||||||
|
// box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
background: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-view {
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.heightClass{height:100%;overflow:hidden;display:flex;width: 100%;flex-direction: column;}
|
||||||
|
|
||||||
|
.mapPaint{
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
width:100%;
|
||||||
|
position:absolute;
|
||||||
|
left:0;top:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-card{
|
||||||
|
width: 550px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
transform: translateX(550px);
|
||||||
|
transition: all 0.5s;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 9;
|
||||||
|
/deep/{
|
||||||
|
.v-modal{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.hide{
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_draft_box{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
padding: 8px 3px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
|
transform: translateX(-22px);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
box-shadow: -2px 0px 2px #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_table_box {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: calc(50% + 50px);
|
||||||
|
padding: 8px 3px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 10;
|
||||||
|
transform: translateX(-22px);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
box-shadow: -2px 0px 2px #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottomBtnGroup{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 43px;
|
||||||
|
text-align: right;
|
||||||
|
right: 0px;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 2;
|
||||||
|
padding-top: 5px;
|
||||||
|
border-bottom: 1px #dedede solid;
|
||||||
|
box-shadow: 2px -3px 5px #dedede;
|
||||||
|
}
|
||||||
|
.bottomBtnGroup button{
|
||||||
|
display: inline-block;
|
||||||
|
margin-right:10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.heightClass .el-card__body{
|
||||||
|
flex:1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#cardTab .el-tabs__content{
|
||||||
|
padding:0px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
186
src/views/iscs_new/iscsDraw/iscsCanvas.vue
Normal file
186
src/views/iscs_new/iscsDraw/iscsCanvas.vue
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div :id="iscsId" v-loading="loading" :style="{ width: width +'px', height: height +'px',background:'#425a74' }" class="iscs-canvas" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Iscs from '@/iscs_new/map';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
import ShapeBuilder from '@/iscs_new/plugins/shapeBuilder';
|
||||||
|
import ShapeProperty from '@/iscs_new/plugins/shapeProperty';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
import ShapeContextMenu from '@/iscs_new/plugins/shapeContextMenu';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataZoom: {
|
||||||
|
offsetX: '0',
|
||||||
|
offsetY: '0',
|
||||||
|
scaleRate: '1'
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
scaleRate: '1',
|
||||||
|
origin: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('iscs', [
|
||||||
|
'iscs'
|
||||||
|
]),
|
||||||
|
iscsId() {
|
||||||
|
return ['iscs', (Math.random().toFixed(5)) * 100000].join('_');
|
||||||
|
},
|
||||||
|
width() {
|
||||||
|
return document.documentElement.clientWidth;
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
return document.documentElement.clientHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.config.canvasSizeCount': function (val) {
|
||||||
|
this.resize();
|
||||||
|
},
|
||||||
|
'$store.state.socket.equipmentStatus': function (val) {
|
||||||
|
if (val.length) {
|
||||||
|
this.stateMessage(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化窗口
|
||||||
|
init() {
|
||||||
|
document.getElementById(this.iscsId).oncontextmenu = function (e) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$iscs = new Iscs({
|
||||||
|
dom: document.getElementById(this.iscsId),
|
||||||
|
draw: true,
|
||||||
|
config: {
|
||||||
|
renderer: 'canvas',
|
||||||
|
width: this.width,
|
||||||
|
height: this.height
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scaleRate: 1,
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 0
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
ShapeBuilder,
|
||||||
|
// ShapeProperty,
|
||||||
|
ShapeContextMenu
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
panEnable: true,
|
||||||
|
zoomEnable: true,
|
||||||
|
keyEnable: true,
|
||||||
|
draggle: true,
|
||||||
|
selecting: true,
|
||||||
|
selectable: true,
|
||||||
|
reflect: true
|
||||||
|
};
|
||||||
|
if (this.$route.query.id) {
|
||||||
|
setTimeout(_ => {
|
||||||
|
Idb.select('composeTemplateList', this.$route.query.id).then(resp => {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: resp.shapeList || [],
|
||||||
|
composeList: resp.composeList || []
|
||||||
|
}, option);
|
||||||
|
EventBus.$emit('getComposeElemList');
|
||||||
|
this.$emit('setStateList', resp.stateList);
|
||||||
|
}).catch(error => {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$iscs = this.$iscs;
|
||||||
|
this.$iscs.on('viewLoaded', this.onViewLoaded, this);
|
||||||
|
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||||
|
this.$iscs.on('click', this.onClick, this);
|
||||||
|
this.$iscs.on('reflect', this.onReflect, this);
|
||||||
|
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||||
|
window.document.oncontextmenu = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 视图加载完成
|
||||||
|
onViewLoaded(e) {
|
||||||
|
},
|
||||||
|
// 键盘快捷键事件
|
||||||
|
onKeyboard(hook) {
|
||||||
|
console.log(hook);
|
||||||
|
},
|
||||||
|
// 点击选择事件
|
||||||
|
onClick(em = {}) {
|
||||||
|
this.$emit('selected', em);
|
||||||
|
},
|
||||||
|
onReflect(em = {}) {
|
||||||
|
this.$emit('selected', this.$iscs.getShapeByCode(em.code));
|
||||||
|
},
|
||||||
|
// 右键点击事件
|
||||||
|
onContextMenu(em = {}) {
|
||||||
|
this.$emit('contextMenu', em.model);
|
||||||
|
},
|
||||||
|
// 执行操作
|
||||||
|
doAction(list) {
|
||||||
|
this.$iscs && this.$iscs.render(list);
|
||||||
|
},
|
||||||
|
// 消息处理
|
||||||
|
stateMessage(val) {
|
||||||
|
this.$iscs && this.$iscs.setDeviceStatus(val);
|
||||||
|
},
|
||||||
|
// 充值窗口大小
|
||||||
|
resize() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$iscs && this.$iscs.resize({ width: this.width, height: this.height });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 销毁
|
||||||
|
destroy() {
|
||||||
|
if (this.$iscs) {
|
||||||
|
this.$iscs.destroy();
|
||||||
|
this.$iscs = null;
|
||||||
|
Vue.prototype.$iscs = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.iscs-button{
|
||||||
|
position: absolute;
|
||||||
|
float: right;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 15px;
|
||||||
|
}
|
||||||
|
.iscs-canvas{
|
||||||
|
}
|
||||||
|
</style>
|
153
src/views/iscs_new/iscsDraw/statusCombineEdit.vue
Normal file
153
src/views/iscs_new/iscsDraw/statusCombineEdit.vue
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="small" class="addComposeStatus" @click="addComposeStatus">添加</el-button>
|
||||||
|
<el-form ref="form" class="composeStatusForm" :model="formModel">
|
||||||
|
<!-- label-width="110px" -->
|
||||||
|
<el-table
|
||||||
|
:data="formModel.stateList"
|
||||||
|
stripe
|
||||||
|
class="composeStatusTable"
|
||||||
|
size="mini"
|
||||||
|
row-key="id"
|
||||||
|
:expand-row-keys="expandKeys"
|
||||||
|
@expand-change="expandChange"
|
||||||
|
>
|
||||||
|
<!-- covertStatusList: -->
|
||||||
|
<el-table-column label="状态" width="98">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.status'"
|
||||||
|
:rules="[{required: true, message:'请输入状态', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.status" size="mini" type="text" style="width:88px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="描述" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.description'"
|
||||||
|
:rules="[{required: true, message:'请输入描述', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.description" size="mini" type="text" style="width:90px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="权重" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.weight'"
|
||||||
|
:rules="[{required: true, message:'请输入权重', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.weight"
|
||||||
|
size="mini"
|
||||||
|
style="width:110px"
|
||||||
|
:step="1"
|
||||||
|
:min="1"
|
||||||
|
:max="100"
|
||||||
|
:precision="0"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否可重置" width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item :prop="'stateList.'+scope.$index+'.needDefault'">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.needDefault"
|
||||||
|
size="small"
|
||||||
|
active-color="#409eff"
|
||||||
|
inactive-color="#dcdfe6"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="115">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="success" size="mini" @click="modifyStatus(scope.$index,scope.row)">编辑状态组合</el-button>
|
||||||
|
<el-button type="danger" size="mini" style="margin-top:5px;" @click="deleteStatus(scope.$index,scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name:'StatusCombineEdit',
|
||||||
|
props:{
|
||||||
|
stateList: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expandKeys:[],
|
||||||
|
formModel:{
|
||||||
|
stateList:this.stateList
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
init() {
|
||||||
|
|
||||||
|
},
|
||||||
|
expandChange(row, expandedRows) {
|
||||||
|
|
||||||
|
},
|
||||||
|
addComposeStatus() {
|
||||||
|
const length = this.formModel.stateList.length;
|
||||||
|
this.formModel.stateList.push({id:length + 1, status:'', description:'', weight:1, needDefault:false,
|
||||||
|
covertStatusList:[]});
|
||||||
|
// defaultLoop:false
|
||||||
|
this.expandKeys.push(length + 1);
|
||||||
|
},
|
||||||
|
deleteStatus(index, row) {
|
||||||
|
this.formModel.stateList.splice(index, 1);
|
||||||
|
const key = this.expandKeys.findIndex(each=>{ return each == row.id; });
|
||||||
|
if (key > 0) { this.expandKeys.splice(key, 1); }
|
||||||
|
},
|
||||||
|
modifyStatus(index, row) {
|
||||||
|
this.$refs.eachStatusTable.doShow(index, row);
|
||||||
|
}
|
||||||
|
// addCovertStatus(index) {
|
||||||
|
// if (this.formModel.stateList[index].defaultLoop) {
|
||||||
|
// const covertStatusList = this.formModel.stateList[index].covertStatusList;
|
||||||
|
// const length = covertStatusList.length;
|
||||||
|
// covertStatusList.push({id:length + 1, loop:this.formModel.stateList[index].defaultLoop,
|
||||||
|
// delay:2, animateTime:10, frameList:[]});
|
||||||
|
// // ,times:1,
|
||||||
|
// // this.formModel.stateList[index].covertStatusList = covertStatusList;
|
||||||
|
// this.$set(this.formModel.stateList[index], 'covertStatusList', covertStatusList);
|
||||||
|
// } else {
|
||||||
|
// this.formModel.stateList[index].covertStatusList.push({id:length + 1, loop:this.formModel.stateList[index].defaultLoop,
|
||||||
|
// frameList:[]});
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.combineStatusListName{
|
||||||
|
font-size: 14px;
|
||||||
|
width: 200px;
|
||||||
|
background: #fff;
|
||||||
|
margin-bottom:10px;
|
||||||
|
}
|
||||||
|
.addComposeStatus{
|
||||||
|
float: right;
|
||||||
|
display: inline-block;
|
||||||
|
margin:10px 10px 10px 0px;
|
||||||
|
}
|
||||||
|
.composeStatusTable{}
|
||||||
|
.composeStatusForm{padding:15px;}
|
||||||
|
.composeStatusTable .eachStatusTable{margin-top:10px;}
|
||||||
|
</style>
|
||||||
|
<style lang="sass">
|
||||||
|
.composeStatusTable .el-table__expanded-cell{padding: 20px;}
|
||||||
|
</style>
|
370
src/views/iscs_new/iscsDraw/statusList.vue
Normal file
370
src/views/iscs_new/iscsDraw/statusList.vue
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-dialogDrag
|
||||||
|
class="composeStatusList"
|
||||||
|
title="状态编辑"
|
||||||
|
:visible.sync="show"
|
||||||
|
width="800px"
|
||||||
|
:before-close="doClose"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<el-button type="primary" size="small" class="addComposeStatus" @click="addComposeStatus">添加</el-button>
|
||||||
|
<el-form ref="form" class="composeStatusForm" :model="formModel">
|
||||||
|
<el-table
|
||||||
|
:data="formModel.stateList"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
class="composeStatusTable"
|
||||||
|
height="360"
|
||||||
|
size="mini"
|
||||||
|
row-key="id"
|
||||||
|
>
|
||||||
|
<el-table-column label="状态" width="169">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.status'"
|
||||||
|
:rules="[{required: true, message:'请输入状态', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.status" size="mini" type="text" style="width:149px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="描述" width="170">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.description'"
|
||||||
|
:rules="[{required: true, message:'请输入描述', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input v-model="scope.row.description" size="mini" type="text" style="width:150px" :maxlength="100" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="权重" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
:prop="'stateList.'+scope.$index+'.weight'"
|
||||||
|
:rules="[{required: true, message:'请输入权重', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input-number v-model="scope.row.weight" size="mini" style="width:100px" :step="1" :min="1" :max="100" :precision="0" />
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否可重置" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item :prop="'stateList.'+scope.$index+'.needDefault'">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.needDefault"
|
||||||
|
size="small"
|
||||||
|
active-color="#409eff"
|
||||||
|
inactive-color="#dcdfe6"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="200">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="success" size="mini" @click="modifyStatus(scope.$index,scope.row)">编辑状态组合</el-button>
|
||||||
|
<el-button type="danger" size="mini" style="margin-top:5px;" @click="deleteStatus(scope.$index,scope.row)">删除</el-button>
|
||||||
|
<!-- <el-button type="primary" size="mini" style="margin-top:5px;" @click="previewStatus(scope.$index,scope.row)">预览</el-button> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button type="primary" size="medium" @click="onEditStatusSave">保存</el-button>
|
||||||
|
</div>
|
||||||
|
<el-dialog
|
||||||
|
v-dialogDrag
|
||||||
|
class="composeStatus"
|
||||||
|
title="状态组合"
|
||||||
|
:visible.sync="innerShow"
|
||||||
|
width="750px"
|
||||||
|
:before-close="doInnerClose"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<div class="loopTitle">是否动画:</div>
|
||||||
|
<el-select v-model="defaultLoop" size="mini">
|
||||||
|
<el-option label="是" :value="true" />
|
||||||
|
<el-option label="否" :value="false" />
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" size="mini" class="addStyle" @click="addCovertStatus">添加</el-button>
|
||||||
|
<el-form ref="Innerform" class="composeStatusForm" :model="statusModel">
|
||||||
|
<el-table
|
||||||
|
:data="statusModel.covertStatusList"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
style="margin-top:10px;"
|
||||||
|
class="eachStatusTable"
|
||||||
|
size="mini"
|
||||||
|
row-key="id"
|
||||||
|
>
|
||||||
|
<el-table-column label="是否动画" width="100" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!-- <el-form-item prop="loop"> -->
|
||||||
|
<div style="">{{ scope.row.loop?'是':'否' }}</div>
|
||||||
|
<!-- </el-form-item> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="动画时间" width="120" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item v-if="scope.row.loop" :prop="'covertStatusList.'+scope.$index+'.animateTime'" :rules="[{required: true, message:'请输入动画时间', trigger: 'blur'}]">
|
||||||
|
<el-input-number v-model="scope.row.animateTime" size="mini" style="width:100px" :step="1" :min="1" :max="100" :precision="0" />
|
||||||
|
</el-form-item>
|
||||||
|
<div v-else>无</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="动画延时" width="120" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-form-item
|
||||||
|
v-if="scope.row.loop"
|
||||||
|
:prop="'covertStatusList.'+scope.$index+'.delay'"
|
||||||
|
:rules="[{required: true, message:'请输入动画延时', trigger: 'blur'}]"
|
||||||
|
>
|
||||||
|
<el-input-number v-model="scope.row.delay" size="mini" style="width:100px" :step="1" :min="1" :max="100" :precision="0" />
|
||||||
|
</el-form-item>
|
||||||
|
<div v-else>无</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态组合" width="319">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<!-- {{ scope.row.frameList }} -->
|
||||||
|
<!-- <div v-if="scope.row.frameList.length<=0"> -->
|
||||||
|
<!-- 元素 -->
|
||||||
|
<!-- <div /> -->
|
||||||
|
<div v-if="scope.row.loop" style="margin-bottom:10px">
|
||||||
|
<!-- <div style="display:inline-block">当前动画帧:{{ scope.row.frameId }}</div> -->
|
||||||
|
<el-button type="primary" size="mini" class="addStyle" @click="addElementFrameId(scope.$index,scope.row.frameId)">添加帧</el-button>
|
||||||
|
<!-- <el-input-number
|
||||||
|
v-model="scope.row.frameId"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
size="mini"
|
||||||
|
:step="1"
|
||||||
|
:precision="0"
|
||||||
|
/> -->
|
||||||
|
</div>
|
||||||
|
<el-select
|
||||||
|
v-model="scope.row.selectedElement"
|
||||||
|
size="mini"
|
||||||
|
style="width:115px;display:inline-block"
|
||||||
|
placeholder="请选择元素"
|
||||||
|
@change="changeCurrentStatus(scope.$index,scope.row.selectedElement)"
|
||||||
|
>
|
||||||
|
<el-option v-for="(element,index) in elementList" :key="index" :label="element.name" :value="element.name" />
|
||||||
|
</el-select>
|
||||||
|
<el-select v-model="scope.row.selectedElementStatus" size="mini" placeholder="请选择状态" style="width:115px;display:inline-block">
|
||||||
|
<el-option v-for="(status,index) in scope.row.statusList" :key="index" :label="status.name" :value="status.name" />
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" size="mini" class="addStyle" @click="addElementStatus(scope.$index,scope.row.loop)">添加</el-button>
|
||||||
|
<div v-if="scope.row.loop">
|
||||||
|
<div v-for="(frame,index) in scope.row.frameList" :key="index">
|
||||||
|
第{{ index+1 }}帧:
|
||||||
|
<span v-for="(frameIn,indexIn) in frame" :key="indexIn">
|
||||||
|
元素名称:{{ frameIn.name }} 状态:{{ frameIn.status }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div v-for="(frame,index) in scope.row.frameList" :key="index">
|
||||||
|
元素名称:{{ frame.name }} 状态:{{ frame.status }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="50">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button type="danger" icon="el-icon-delete" circle size="mini" @click="deleteCovertStatus(scope.$index,scope.row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form>
|
||||||
|
<div class="bottomBtnGroup">
|
||||||
|
<el-button type="primary" size="medium" @click="onEditComposeStatus">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { deepAssign } from '@/utils/index';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
export default {
|
||||||
|
name:'StatusList',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show:false,
|
||||||
|
defaultLoop:false,
|
||||||
|
// covertStatusList:[],
|
||||||
|
innerShow:false,
|
||||||
|
formModel:{
|
||||||
|
stateList:[]
|
||||||
|
},
|
||||||
|
statusModel:{
|
||||||
|
covertStatusList:[]
|
||||||
|
},
|
||||||
|
elementList:[],
|
||||||
|
currentIndex:0,
|
||||||
|
model:{}
|
||||||
|
// statusList:[]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
doClose() {
|
||||||
|
this.show = false;
|
||||||
|
},
|
||||||
|
doShow() {
|
||||||
|
this.formModel.stateList = [];
|
||||||
|
this.show = true;
|
||||||
|
Idb.select('composeTemplateList', this.$route.query.id).then(resp => {
|
||||||
|
this.formModel.stateList = resp.stateList;
|
||||||
|
this.model = resp;
|
||||||
|
}).catch(() => {
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addComposeStatus() {
|
||||||
|
const length = this.formModel.stateList.length;
|
||||||
|
this.formModel.stateList.push({id:length + 1, status:'', description:'', weight:1, needDefault:false,
|
||||||
|
covertStatusList:[]});
|
||||||
|
},
|
||||||
|
deleteStatus(index, row) {
|
||||||
|
this.formModel.stateList.splice(index, 1);
|
||||||
|
},
|
||||||
|
onEditStatusSave() {
|
||||||
|
const that = this;
|
||||||
|
that.$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
// that.formModel;
|
||||||
|
// // const id = this.$route.query.id;
|
||||||
|
this.model.stateList = that.formModel.stateList;
|
||||||
|
Idb.delete('composeTemplateList', this.model.id);
|
||||||
|
Idb.write('composeTemplateList', this.model);
|
||||||
|
that.show = false;
|
||||||
|
this.$emit('setStateList', that.formModel.stateList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
modifyStatus(index, row) {
|
||||||
|
this.currentIndex = index;
|
||||||
|
this.innerShow = true;
|
||||||
|
this.statusModel.covertStatusList = Object.values(row.covertStatusList);
|
||||||
|
const source = this.$iscs.getSource();
|
||||||
|
const composeElemList = source.elementList;
|
||||||
|
this.elementList = [];
|
||||||
|
composeElemList.forEach(each=>{
|
||||||
|
this.elementList.push({name:each.name, stateList:each.stateList});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
doInnerClose() {
|
||||||
|
this.innerShow = false;
|
||||||
|
},
|
||||||
|
addCovertStatus() {
|
||||||
|
if (this.defaultLoop) {
|
||||||
|
this.statusModel.covertStatusList.push({loop:this.defaultLoop, delay:2, animateTime:10, frameList:[], statusList:[], selectedElement:'', selectedElementStatus:'', frameId:null });
|
||||||
|
} else {
|
||||||
|
this.statusModel.covertStatusList.push({loop:this.defaultLoop, frameList:[], statusList:[], selectedElementStatus:'', selectedElement:'' });
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onEditComposeStatus() {
|
||||||
|
this.innerShow = false;
|
||||||
|
this.statusModel.covertStatusList.forEach(covert=>{
|
||||||
|
delete covert.selectedElement;
|
||||||
|
delete covert.selectedElementStatus;
|
||||||
|
delete covert.statusList;
|
||||||
|
delete covert.frameId;
|
||||||
|
});
|
||||||
|
this.formModel.stateList[this.currentIndex].covertStatusList = deepAssign({}, this.statusModel.covertStatusList);
|
||||||
|
},
|
||||||
|
deleteCovertStatus(index, row) {
|
||||||
|
this.statusModel.covertStatusList.splice(index, 1);
|
||||||
|
},
|
||||||
|
addElementFrameId(index, frameId) {
|
||||||
|
if (frameId) {
|
||||||
|
this.statusModel.covertStatusList[index].frameId = frameId + 1;
|
||||||
|
} else {
|
||||||
|
this.statusModel.covertStatusList[index].frameId = 1;
|
||||||
|
}
|
||||||
|
this.statusModel.covertStatusList[index].frameList.push([]);
|
||||||
|
},
|
||||||
|
addElementStatus(index, loop) {
|
||||||
|
const frameList = this.statusModel.covertStatusList[index].frameList || [];
|
||||||
|
const temp = this.statusModel.covertStatusList[index];
|
||||||
|
if (loop) {
|
||||||
|
if (temp.selectedElement && temp.selectedElementStatus && temp.frameId) {
|
||||||
|
const curFrame = frameList[temp.frameId];
|
||||||
|
let curFrameIndex = -1;
|
||||||
|
if (curFrame && curFrame.length > 0) {
|
||||||
|
curFrameIndex = curFrame.findIndex(frame=>{
|
||||||
|
return frame.name == this.statusModel.covertStatusList[index].selectedElement &&
|
||||||
|
frame.status == this.statusModel.covertStatusList[index].selectedElementStatus;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (curFrameIndex < 0) {
|
||||||
|
// this.statusModel.covertStatusList[index].frameList.push([]);
|
||||||
|
this.statusModel.covertStatusList[index].frameList[temp.frameId - 1].push({name:this.statusModel.covertStatusList[index].selectedElement,
|
||||||
|
status:this.statusModel.covertStatusList[index].selectedElementStatus});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (temp.selectedElement && temp.selectedElementStatus) {
|
||||||
|
const indexFrame = frameList.findIndex(frame=>{
|
||||||
|
return frame.name == this.statusModel.covertStatusList[index].selectedElement &&
|
||||||
|
frame.status == this.statusModel.covertStatusList[index].selectedElementStatus;
|
||||||
|
});
|
||||||
|
if (indexFrame < 0) {
|
||||||
|
this.statusModel.covertStatusList[index].frameList.push({name:this.statusModel.covertStatusList[index].selectedElement,
|
||||||
|
status:this.statusModel.covertStatusList[index].selectedElementStatus});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.statusModel.covertStatusList[index].selectedElementStatus = '';
|
||||||
|
this.statusModel.covertStatusList[index].selectedElement = '';
|
||||||
|
},
|
||||||
|
changeCurrentStatus(index, selectedElement) {
|
||||||
|
this.statusModel.covertStatusList[index].selectedElementStatus = '';
|
||||||
|
this.statusModel.covertStatusList[index].statusList = [];
|
||||||
|
const list = this.elementList.find(each=>{ return each.name == selectedElement; });
|
||||||
|
if (list && list.stateList && list.stateList.length > 0) {
|
||||||
|
const temp = list.stateList;
|
||||||
|
temp.forEach(each=>{
|
||||||
|
this.statusModel.covertStatusList[index].statusList.push({name:each.status});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// previewStatus(index, row) {
|
||||||
|
// // const that = this;
|
||||||
|
// // if(needDefault)
|
||||||
|
// const list = Object.values(row.covertStatusList);
|
||||||
|
// list.forEach(each=>{
|
||||||
|
// if (each.loop) {
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// const frameList = each.frameList;
|
||||||
|
// frameList.forEach(frame=>{
|
||||||
|
// // frame.name;
|
||||||
|
// // frame.status;
|
||||||
|
// // this.$iscs.
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// // this.show = false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.composeStatusTable{margin-top:10px;}
|
||||||
|
.bottomBtnGroup{
|
||||||
|
width: 100%;
|
||||||
|
margin-top:10px;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block
|
||||||
|
}
|
||||||
|
.loopTitle{display:inline-block;}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.composeStatusList .el-dialog__body,.composeStatus .el-dialog__body{padding: 15px 20px;}
|
||||||
|
</style>
|
192
src/views/iscs_new/iscsPreview/index.vue
Normal file
192
src/views/iscs_new/iscsPreview/index.vue
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-center">
|
||||||
|
<div class="mapPaint">
|
||||||
|
<div class="map-view">
|
||||||
|
<iscs-canvas ref="iscsCanvas" @selected="onSelected" @setData="setData" />
|
||||||
|
</div>
|
||||||
|
<div class="right-card">
|
||||||
|
<!-- :class="{'hide': draftShow}" -->
|
||||||
|
<el-card type="border-card" class="heightClass">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<!-- 组件id为{{ $route.query.id }} -->
|
||||||
|
状态预览
|
||||||
|
<!-- -->
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
style="float: right; padding: 3px 0; margin-right: 5px;"
|
||||||
|
@click="resetDefaultStatus"
|
||||||
|
>重置状态</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="stateList">
|
||||||
|
<!-- <el-card style="margin-top:10px;height:100%"> -->
|
||||||
|
<div v-for="(state,index) in stateList" :key="index" class="eachStatus">
|
||||||
|
<div>状态属性:{{ state.status }}</div>
|
||||||
|
<div>状态描述:{{ state.description }}</div>
|
||||||
|
<div>状态权重:{{ state.weight }}</div>
|
||||||
|
<div>状态是否可以初始化:{{ state.needDefault?'是':'否' }}</div>
|
||||||
|
<el-button type="primary" size="mini" style="margin-top:5px;" @click="previewStatus(state)">预览</el-button>
|
||||||
|
</div>
|
||||||
|
<!-- </el-card> -->
|
||||||
|
<!-- <el-tabs v-model="statusTab" class="card" type="card" @tab-click="onSelectTab"> -->
|
||||||
|
<!-- <el-tab-pane v-for="(composeElem,index) in composeElemList" :key="index" :label="composeElem.name" :name="composeElem.code" :lazy="true"> -->
|
||||||
|
<!-- <table-form :ref="'tableform'+composeElem.code" :compose-elem="composeElem" /> -->
|
||||||
|
<!-- stateList -->
|
||||||
|
<!-- </el-tab-pane> -->
|
||||||
|
<!-- </el-tabs> -->
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
import iscsCanvas from './iscsCanvas';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType.js';
|
||||||
|
export default {
|
||||||
|
name:'IscsPreview',
|
||||||
|
components: {
|
||||||
|
iscsCanvas
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
draftShow: false,
|
||||||
|
selected: null,
|
||||||
|
statusTab:'',
|
||||||
|
stateList:[],
|
||||||
|
elementList:[],
|
||||||
|
type:''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
onSelectTab() {
|
||||||
|
|
||||||
|
},
|
||||||
|
setData(data) {
|
||||||
|
this.stateList = data.stateList;
|
||||||
|
this.elementList = utils.deepClone(data.shapeList);
|
||||||
|
this.type = data.type;
|
||||||
|
},
|
||||||
|
previewStatus(data) {
|
||||||
|
// this.resetDefaultStatus();
|
||||||
|
// covertStatusList: Object
|
||||||
|
// description: "关闭"
|
||||||
|
// id: 1
|
||||||
|
// needDefault: true
|
||||||
|
// status: "close"
|
||||||
|
// weight: 1
|
||||||
|
this.$iscs.update([
|
||||||
|
{ status: data.status, code: '100', type: this.type }
|
||||||
|
]);
|
||||||
|
// const that = this;
|
||||||
|
// const list = Object.values(data.covertStatusList);
|
||||||
|
// list.forEach(each=>{
|
||||||
|
// debugger;
|
||||||
|
// if (each.loop) {
|
||||||
|
// // ChangeStatus
|
||||||
|
// } else {
|
||||||
|
// const frameList = each.frameList;
|
||||||
|
// // <模型类型>
|
||||||
|
// // this.$iscs.update([
|
||||||
|
// // { status: 's1', code: '100', type: 'Device' },
|
||||||
|
// // { status: 's2', code: '101', type: 'Device' }
|
||||||
|
// // ]);
|
||||||
|
// frameList.forEach(frame=>{
|
||||||
|
// const element = that.elementList.find(ele=>{ return ele.name == frame.name; });
|
||||||
|
// if (element) {
|
||||||
|
// const elementStyle = element.stateList.find(state=>{ return state.status == frame.status; });
|
||||||
|
// if (elementStyle) {
|
||||||
|
// const model = utils.deepClone(element);
|
||||||
|
|
||||||
|
// // this.$iscs.update([
|
||||||
|
// // { status: 's1', code: '100', type: 'Device' },
|
||||||
|
// // { status: 's2', code: '101', type: 'Device' }
|
||||||
|
// // ]);
|
||||||
|
|
||||||
|
// // model.frameList = [];
|
||||||
|
// // const style = elementStyle.style || {};
|
||||||
|
// // // model.changeStyle =
|
||||||
|
// // if (style && JSON.stringify(style) != '{}') {
|
||||||
|
// // const keys = Object.keys(style);
|
||||||
|
// // keys.forEach(eachKey=>{
|
||||||
|
// // model.style[eachKey] = style[eachKey];
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// // const shape = elementStyle.shape || {};
|
||||||
|
// // if (shape && JSON.stringify(shape) != '{}') {
|
||||||
|
// // const keys = Object.keys(shape);
|
||||||
|
// // keys.forEach(eachShape=>{
|
||||||
|
// // model.shape[eachShape] = style[eachShape];
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// // { status: 's1', code: '100', type: 'Device' },
|
||||||
|
// // this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Update}}]);
|
||||||
|
// this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.ChangeStatus}}]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
resetDefaultStatus() {
|
||||||
|
this.elementList.forEach(element=>{
|
||||||
|
const model = utils.deepClone(element);
|
||||||
|
this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.Update}}]);
|
||||||
|
// this.$refs.iscsCanvas.doAction([{model, action: {shapeType: shapeType.Element, order: orders.ResetStatus}}]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// getComposeElemList() {
|
||||||
|
// const source = this.$iscs.getSource();
|
||||||
|
// if (source &&
|
||||||
|
// source.elementList &&
|
||||||
|
// source.elementList.length) {
|
||||||
|
// this.composeElemList = source.elementList;
|
||||||
|
// this.statusTab = this.composeElemList[0].code;
|
||||||
|
// } else {
|
||||||
|
// this.composeElemList = [];
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
onSelected(em) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mapPaint{
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
width:100%;
|
||||||
|
position:absolute;
|
||||||
|
left:0;top:0;
|
||||||
|
}
|
||||||
|
.right-card{
|
||||||
|
width: 500px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top:0;
|
||||||
|
transition: all 0.5s;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
.heightClass{height:100%;overflow:hidden;display:flex;width: 100%;flex-direction: column;}
|
||||||
|
.eachStatus{
|
||||||
|
padding: 15px 30px;
|
||||||
|
border-bottom: 1px #ccc solid;
|
||||||
|
line-height: 150%;
|
||||||
|
}
|
||||||
|
.statelist{
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss">
|
||||||
|
.heightClass .el-card__body{
|
||||||
|
flex:1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
185
src/views/iscs_new/iscsPreview/iscsCanvas.vue
Normal file
185
src/views/iscs_new/iscsPreview/iscsCanvas.vue
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div :id="iscsId" v-loading="loading" :style="{ width: width +'px', height: height +'px',background:'#425a74' }" class="iscs-canvas" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Iscs from '@/iscs_new/map';
|
||||||
|
import Idb from '../utils/indexedDb.js';
|
||||||
|
import ShapeBuilder from '@/iscs_new/plugins/shapeBuilder';
|
||||||
|
import ShapeProperty from '@/iscs_new/plugins/shapeProperty';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
import ShapeContextMenu from '@/iscs_new/plugins/shapeContextMenu';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dataZoom: {
|
||||||
|
offsetX: '0',
|
||||||
|
offsetY: '0',
|
||||||
|
scaleRate: '1'
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
scaleRate: '1',
|
||||||
|
origin: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('iscs', [
|
||||||
|
'iscs'
|
||||||
|
]),
|
||||||
|
iscsId() {
|
||||||
|
return ['iscs', (Math.random().toFixed(5)) * 100000].join('_');
|
||||||
|
},
|
||||||
|
width() {
|
||||||
|
return document.documentElement.clientWidth;
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
return document.documentElement.clientHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.config.canvasSizeCount': function (val) {
|
||||||
|
this.resize();
|
||||||
|
},
|
||||||
|
'$store.state.socket.equipmentStatus': function (val) {
|
||||||
|
if (val.length) {
|
||||||
|
this.stateMessage(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化窗口
|
||||||
|
init() {
|
||||||
|
document.getElementById(this.iscsId).oncontextmenu = function (e) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$iscs = new Iscs({
|
||||||
|
dom: document.getElementById(this.iscsId),
|
||||||
|
draw: true,
|
||||||
|
config: {
|
||||||
|
renderer: 'canvas',
|
||||||
|
width: this.width,
|
||||||
|
height: this.height
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scaleRate: 1,
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 0
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// ShapeBuilder,
|
||||||
|
// ShapeProperty,
|
||||||
|
// ShapeContextMenu
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
panEnable: true,
|
||||||
|
zoomEnable: true,
|
||||||
|
keyEnable: true,
|
||||||
|
draggle: false,
|
||||||
|
selecting: false,
|
||||||
|
selectable: false,
|
||||||
|
reflect: true
|
||||||
|
};
|
||||||
|
if (this.$route.query.id) {
|
||||||
|
setTimeout(_ => {
|
||||||
|
Idb.select('composeTemplateList', this.$route.query.id).then(resp => {
|
||||||
|
this.$iscs.setMap([resp], {
|
||||||
|
elementList: resp.shapeList || [],
|
||||||
|
composeList: resp.composeList || []
|
||||||
|
}, option);
|
||||||
|
this.$emit('setData', resp);
|
||||||
|
}).catch(error => {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
this.$iscs.setMap([], {
|
||||||
|
elementList: [],
|
||||||
|
composeList: []
|
||||||
|
}, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$iscs = this.$iscs;
|
||||||
|
this.$iscs.on('viewLoaded', this.onViewLoaded, this);
|
||||||
|
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||||
|
// this.$iscs.on('click', this.onClick, this);
|
||||||
|
this.$iscs.on('reflect', this.onReflect, this);
|
||||||
|
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||||
|
window.document.oncontextmenu = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 视图加载完成
|
||||||
|
onViewLoaded(e) {
|
||||||
|
},
|
||||||
|
// 键盘快捷键事件
|
||||||
|
onKeyboard(hook) {
|
||||||
|
console.log(hook);
|
||||||
|
},
|
||||||
|
// 点击选择事件
|
||||||
|
onClick(em = {}) {
|
||||||
|
this.$emit('selected', em);
|
||||||
|
},
|
||||||
|
onReflect(em = {}) {
|
||||||
|
this.$emit('selected', this.$iscs.getShapeByCode(em.code));
|
||||||
|
},
|
||||||
|
// 右键点击事件
|
||||||
|
onContextMenu(em = {}) {
|
||||||
|
this.$emit('contextMenu', em.model);
|
||||||
|
},
|
||||||
|
// 执行操作
|
||||||
|
doAction(list) {
|
||||||
|
this.$iscs && this.$iscs.render(list);
|
||||||
|
},
|
||||||
|
// 消息处理
|
||||||
|
stateMessage(val) {
|
||||||
|
this.$iscs && this.$iscs.setDeviceStatus(val);
|
||||||
|
},
|
||||||
|
// 充值窗口大小
|
||||||
|
resize() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$iscs && this.$iscs.resize({ width: this.width, height: this.height });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 销毁
|
||||||
|
destroy() {
|
||||||
|
if (this.$iscs) {
|
||||||
|
this.$iscs.destroy();
|
||||||
|
this.$iscs = null;
|
||||||
|
Vue.prototype.$iscs = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.iscs-button{
|
||||||
|
position: absolute;
|
||||||
|
float: right;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 15px;
|
||||||
|
}
|
||||||
|
.iscs-canvas{
|
||||||
|
}
|
||||||
|
</style>
|
140
src/views/iscs_new/utils/indexedDb.js
Normal file
140
src/views/iscs_new/utils/indexedDb.js
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
|
||||||
|
import { getBaseUrl } from '@/utils/baseUrl'
|
||||||
|
|
||||||
|
let db = null;
|
||||||
|
class IndexedDb {
|
||||||
|
constructor(nameList) {
|
||||||
|
this.open(nameList);
|
||||||
|
}
|
||||||
|
|
||||||
|
open(nameList) {
|
||||||
|
const baseUrl = getBaseUrl();
|
||||||
|
const indexedDBName = baseUrl.replace(/http.?:\/\/(.*)[\/|:].*/, "$1");
|
||||||
|
const request = window.indexedDB.open(indexedDBName, 1);
|
||||||
|
request.onerror = function (e) {
|
||||||
|
console.log('数据库打开报错');
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onsuccess = function (e) {
|
||||||
|
db = request.result;
|
||||||
|
console.log('数据库打开成功');
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onupgradeneeded = function (e) {
|
||||||
|
db = e.target.result;
|
||||||
|
nameList.forEach(name => {
|
||||||
|
db.createObjectStore(name, { keyPath: 'id' });
|
||||||
|
console.log(name);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
write(tableName, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (db) {
|
||||||
|
const request = db.transaction([tableName], 'readwrite').objectStore(tableName).add(data);
|
||||||
|
request.onsuccess = function(e) {
|
||||||
|
console.log('数据写入成功');
|
||||||
|
resolve(request.result);
|
||||||
|
};
|
||||||
|
request.onerror = function(e) {
|
||||||
|
console.log('数据写入失败');
|
||||||
|
reject(e);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
reject({message: '数据库未打开!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(tableName, key) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (db) {
|
||||||
|
const request = db.transaction([tableName], 'readwrite').objectStore(tableName).delete(key);
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
console.log('数据删除成功');
|
||||||
|
resolve(request.result);
|
||||||
|
};
|
||||||
|
request.onerror = function(event) {
|
||||||
|
console.log('数据删除失败');
|
||||||
|
reject(event);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
reject({message: '数据库未打开!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
modify(tableName, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (db) {
|
||||||
|
const request = db.transaction([tableName], 'readwrite').objectStore(tableName).put(data);
|
||||||
|
request.onsuccess = function(e) {
|
||||||
|
console.log('数据修改成功');
|
||||||
|
resolve(request.result);
|
||||||
|
};
|
||||||
|
request.onerror = function(e) {
|
||||||
|
console.log('数据修改失败');
|
||||||
|
reject(e);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
reject({message: '数据库未打开!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
select(tableName, key) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (db) {
|
||||||
|
const request = db.transaction([tableName]).objectStore(tableName).get(key);
|
||||||
|
request.onsuccess = function(e) {
|
||||||
|
console.log('数据查询成功');
|
||||||
|
resolve(request.result);
|
||||||
|
};
|
||||||
|
request.onerror = function(e) {
|
||||||
|
console.log('数据查询失败');
|
||||||
|
reject(e);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
reject({message: '数据库未打开!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
list(tableName) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (db) {
|
||||||
|
const store = db.transaction([tableName]).objectStore(tableName);
|
||||||
|
|
||||||
|
var request = store.openCursor();
|
||||||
|
var list = [];
|
||||||
|
request.onsuccess = function(e) {
|
||||||
|
var c = e.target.result;
|
||||||
|
if (c) {
|
||||||
|
list.push(c.value);
|
||||||
|
c.continue();
|
||||||
|
} else {
|
||||||
|
resolve(list);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.onerror = function(e) {
|
||||||
|
console.log('数据读取失败');
|
||||||
|
reject(e);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.open();
|
||||||
|
reject({message: '数据库未打开!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new IndexedDb(['composeList']);
|
||||||
|
|
284
src/views/newMap/displayCity/demon/addFault.vue
Normal file
284
src/views/newMap/displayCity/demon/addFault.vue
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
<template>
|
||||||
|
<div class="addRules">
|
||||||
|
<div class="addRulesInner">
|
||||||
|
<div class="addRulesInnerTitle">新增故障</div>
|
||||||
|
<div class="closeAddRulesInner" @click="addRulesClose">
|
||||||
|
<span class="el-icon-close closeAddRulesIn" />
|
||||||
|
</div>
|
||||||
|
<el-form ref="form" :model="faultRule" label-width="100px" style="margin-left:15px;">
|
||||||
|
<el-form-item label="目标设备">
|
||||||
|
<!-- faultRule.targetDeviceCode -->
|
||||||
|
<el-input v-model="targetDevice.name" disabled size="small" class="inputModelClass" />
|
||||||
|
<!--<el-button :type="field === 'targetActive' ? 'danger' : 'primary'" size="small" @click="hover('targetActive')">{{ $t('map.activate') }}</el-button>-->
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="触发方式">
|
||||||
|
<el-select v-model="triggerMode" @change="changeTriggerMode">
|
||||||
|
<el-option
|
||||||
|
v-for="item in triggerModeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="故障类型">
|
||||||
|
<el-select v-model="faultRule.faultType" placeholder="请选择" class="inputModelClass">
|
||||||
|
<el-option
|
||||||
|
v-for="item in faultTypeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'DEVICE'" label="触发设备">
|
||||||
|
<!-- faultRule.condition.triggerDeviceCode -->
|
||||||
|
<el-input v-model="triggerDevice" size="small" disabled class="inputModelClass" />
|
||||||
|
<el-button :type="field === 'triggerActive' ? 'danger' : 'primary'" size="small" @click="hover('triggerActive')">{{ $t('map.activate') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'DEVICE'" label="触发状态">
|
||||||
|
<!-- <el-input v-model="faultRule.condition.triggerDeviceStatus" size="small" class="inputModelClass" /> -->
|
||||||
|
<el-select v-model="faultRule.condition.triggerDeviceStatus" placeholder="请选择" class="inputModelClass">
|
||||||
|
<el-option
|
||||||
|
v-for="item in triggerStatusList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'DEVICE'" label="关联设备">
|
||||||
|
<el-input v-model="triggerAssociatedDevice" size="small" disabled class="inputModelClass" />
|
||||||
|
<el-button :type="field === 'triggerAssociated'? 'danger': 'primary'" size="small" @click="hover('triggerAssociated')">{{ $t('map.activate') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'TIME'" label="触发时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="faultRule.condition.triggeringTime"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span class="addRulesFooter">
|
||||||
|
<el-button size="medium" type="primary" @click="addRulesCreate">{{ $t('global.confirm') }}</el-button>
|
||||||
|
<el-button size="medium" @click="addRulesClose">{{ $t('global.cancel') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { FaultStatusEnum } from '@/scripts/FaultDicNew';
|
||||||
|
import { setFailureModeNew} from '@/api/simulation';
|
||||||
|
import { deviceFaultType} from '@/scripts/cmdPlugin/Config';
|
||||||
|
// 添加故障
|
||||||
|
export default {
|
||||||
|
name: 'AddChoose',
|
||||||
|
props: {
|
||||||
|
targetDevice: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
field:'',
|
||||||
|
triggerStatusList:[],
|
||||||
|
faultTypeList:[],
|
||||||
|
faultRule:{
|
||||||
|
targetDeviceCode:'',
|
||||||
|
targetDeviceType:'',
|
||||||
|
faultType:'',
|
||||||
|
condition:{
|
||||||
|
triggerDeviceCode:'',
|
||||||
|
triggerDeviceStatus:'',
|
||||||
|
triggerDeviceType :'',
|
||||||
|
type:'DEVICE',
|
||||||
|
triggeringTime: '',
|
||||||
|
triggerAssociatedDeviceCode: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// targetDevice:'',
|
||||||
|
triggerDevice:'',
|
||||||
|
triggerAssociatedDevice: '',
|
||||||
|
triggerMode: 'DEVICE',
|
||||||
|
triggerModeList: [
|
||||||
|
{label: '设备触发', value: 'DEVICE'},
|
||||||
|
{label: '时间触发', value: 'TIME'}
|
||||||
|
]
|
||||||
|
// rules:{
|
||||||
|
// targetDevice:[
|
||||||
|
// { required: true, message:'请选择目标设备', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// triggerDevice:[
|
||||||
|
// { required: true, message:'请选择触发设备', trigger: 'blur' }
|
||||||
|
// ],
|
||||||
|
// faultRule:{
|
||||||
|
// faultType:[
|
||||||
|
// { required: true, message:'请选择故障类型', trigger: 'blur' },
|
||||||
|
// { required: true, message:'请选择故障类型', trigger: 'change' }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.menuOperation.selectedCount':function(em) {
|
||||||
|
const device = this.$store.state.menuOperation.selected;
|
||||||
|
if (device.code) {
|
||||||
|
this.deviceSelect(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
deviceSelect(em) {
|
||||||
|
if (this.field.toUpperCase() === 'triggerAssociated'.toUpperCase()) {
|
||||||
|
// if (em._type == 'Station') {
|
||||||
|
// em = this.$store.getters['map/getDeviceByCode'](em.zcCode);
|
||||||
|
// }
|
||||||
|
// this.faultRule.targetDeviceType = this.covertType(em._type);
|
||||||
|
// this.faultRule.targetDeviceCode = em.code;
|
||||||
|
if (em._type.toUpperCase() === 'Section'.toUpperCase() && em.parentName) {
|
||||||
|
this.triggerAssociatedDevice = em._type + '-' + em.parentName + '-' + em.name;
|
||||||
|
} else {
|
||||||
|
this.triggerAssociatedDevice = em._type + '-' + em.name;
|
||||||
|
}
|
||||||
|
this.faultRule.condition.triggerAssociatedDeviceCode = em.code;
|
||||||
|
} else if (this.field.toUpperCase() === 'triggerActive'.toUpperCase()) {
|
||||||
|
this.faultRule.condition.triggerDeviceType = this.covertType(em._type);
|
||||||
|
this.faultRule.condition.triggerDeviceCode = em.code;
|
||||||
|
if (em._type.toUpperCase() === 'Section'.toUpperCase() && em.parentName) {
|
||||||
|
this.triggerDevice = em._type + '-' + em.parentName + '-' + em.name;
|
||||||
|
} else if (em._type.toUpperCase() === 'Train'.toUpperCase()) {
|
||||||
|
this.triggerDevice = em._type + '-' + em.code;
|
||||||
|
} else {
|
||||||
|
this.triggerDevice = em._type + '-' + em.name;
|
||||||
|
}
|
||||||
|
this.triggerStatusList = [];
|
||||||
|
const faultStatus = FaultStatusEnum[this.faultRule.condition.triggerDeviceType];
|
||||||
|
if (faultStatus) {
|
||||||
|
const list = Object.keys(faultStatus);
|
||||||
|
list.forEach(key=>{
|
||||||
|
this.triggerStatusList.push({label:faultStatus[key], value:key});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.field = '';
|
||||||
|
this.faultRule.condition.triggerDeviceStatus = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
covertType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'Section':return 'SECTION';
|
||||||
|
case 'Signal':return 'SIGNAL';
|
||||||
|
case 'Switch':return 'SWITCH';
|
||||||
|
case 'Station':return 'STATION';
|
||||||
|
case 'ZcControl':return 'ZC';
|
||||||
|
case 'StationStand':return 'STAND';
|
||||||
|
case 'Train':return 'TRAIN';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hover(field) {
|
||||||
|
if (this.field == '') {
|
||||||
|
this.field = field;
|
||||||
|
} else {
|
||||||
|
this.field = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addRulesCreate() {
|
||||||
|
if (this.triggerDevice == '') {
|
||||||
|
this.$messageBox('请选择触发设备');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.faultRule.condition.triggerDeviceStatus == '') {
|
||||||
|
this.$messageBox('请选择触发状态');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.faultRule.faultType == '') {
|
||||||
|
this.$messageBox('请选择故障类型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(this.faultRule, '-------------');
|
||||||
|
setFailureModeNew(this.faultRule, this.$route.query.group).then(res=>{
|
||||||
|
this.$emit('closeAddRules');
|
||||||
|
this.$emit('reload');
|
||||||
|
}).catch((error)=>{
|
||||||
|
this.$messageBox('创建故障失败: ' + error.message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addRulesClose() {
|
||||||
|
this.resetForm();
|
||||||
|
this.$emit('closeAddRules');
|
||||||
|
},
|
||||||
|
|
||||||
|
initValue() {
|
||||||
|
this.faultTypeList = deviceFaultType[this.targetDevice._type];
|
||||||
|
this.faultRule.targetDeviceCode = this.targetDevice.code;
|
||||||
|
this.faultRule.targetDeviceType = this.covertType(this.targetDevice._type);
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.triggerDevice = '';
|
||||||
|
this.faultRule = {
|
||||||
|
targetDeviceCode:'',
|
||||||
|
targetDeviceType:'',
|
||||||
|
faultType:'',
|
||||||
|
condition:{
|
||||||
|
triggerDeviceCode:'',
|
||||||
|
triggerDeviceStatus:'',
|
||||||
|
triggerDeviceType :'',
|
||||||
|
type:'DEVICE',
|
||||||
|
triggeringTime: '',
|
||||||
|
triggerAssociatedDeviceCode: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.addRules{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 40px;
|
||||||
|
}
|
||||||
|
.addRulesInner{
|
||||||
|
position: relative;
|
||||||
|
width: 380px;
|
||||||
|
margin-top:6px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px #ccc solid;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
box-shadow: 3px 3px 3px #a0a0a0;
|
||||||
|
z-index:2;
|
||||||
|
}
|
||||||
|
.queryList{
|
||||||
|
height: 300px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.inputModelClass{
|
||||||
|
width:150px;
|
||||||
|
}
|
||||||
|
.addRulesInnerTitle{
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.closeAddRulesInner{
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 9px;
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.closeAddRulesIn{
|
||||||
|
font-size: 19px;
|
||||||
|
}
|
||||||
|
.addRulesFooter{
|
||||||
|
margin-left: 116px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
196
src/views/newMap/displayCity/demon/equipment.vue
Normal file
196
src/views/newMap/displayCity/demon/equipment.vue
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-drawer
|
||||||
|
title="设备管理"
|
||||||
|
:visible.sync="show"
|
||||||
|
direction="ltr"
|
||||||
|
:before-close="doClose"
|
||||||
|
custom-class="dialog_box"
|
||||||
|
size="43%"
|
||||||
|
>
|
||||||
|
<div style="margin-bottom: 3px; overflow: hidden; padding: 0 10px;">
|
||||||
|
<div class="plc_box">名称: {{ plcInfo.name }}</div>
|
||||||
|
<div class="plc_box">状态: <span :style="{'color': plcInfo.status ? 'green' : 'red'}">{{ plcInfo.status ? '在线' : '不在线' }}</span></div>
|
||||||
|
<el-button type="text" size="small" class="freshen_box" @click="getList">刷新</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="tableData" border style="width: 100%; max-height: calc(100% - 24px); overflow: auto;">
|
||||||
|
<el-table-column prop="code" label="设备编号" width="180" />
|
||||||
|
<el-table-column prop="typeName" label="设备类型" width="180" />
|
||||||
|
<el-table-column prop="vrDeviceCode" label="连接设备编码">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div v-if="scope.row.vrDeviceCode" class="flex_box">{{ scope.row.vrDeviceName }}</div>
|
||||||
|
<div v-if="!scope.row.vrDeviceCode" class="flex_box">(空)</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button :type="scope.row.buttonShowType ? 'danger' : 'primary'" size="small" @click="handleClick(scope.row, scope.$index)">连接</el-button>
|
||||||
|
<el-button size="small" @click="cancel(scope.row, scope.$index)">断开</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAllSimulationList, postSimulationConnectById, putSimulationDisconnectById } from '@/api/simulation.js';
|
||||||
|
import ConstConfig from '@/scripts/ConstConfig';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
import { getSessionStorage } from '@/utils/auth';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Equipment',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
group: '',
|
||||||
|
tableData: [],
|
||||||
|
typeList: ConstConfig.ConstSelect.projectDeviceTypeList,
|
||||||
|
plcInfo: {
|
||||||
|
name: '',
|
||||||
|
status: ''
|
||||||
|
},
|
||||||
|
index: 0,
|
||||||
|
selected: {},
|
||||||
|
typeObj: {
|
||||||
|
Section: '区段',
|
||||||
|
Signal: '信号机',
|
||||||
|
Switch: '道岔',
|
||||||
|
Psd: '屏蔽门',
|
||||||
|
StationStand: '站台'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
project() {
|
||||||
|
return getSessionStorage('project');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
EventBus.$on('selectDevice', (data) => {
|
||||||
|
this.selected = data;
|
||||||
|
this.tableData[this.index]['buttonShowType'] = false;
|
||||||
|
this.tableData.splice(this.index, 1, this.tableData[this.index]);
|
||||||
|
this.$store.dispatch('map/selectDeviceCode', {flag: false, type: ''});
|
||||||
|
this.connect(this.tableData[this.index]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async beforeDestroy() {
|
||||||
|
EventBus.$off('selectDevice');
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async doShow() {
|
||||||
|
this.show = true;
|
||||||
|
this.group = this.$route.query.group;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
const res = await getAllSimulationList(this.group);
|
||||||
|
this.tableData = [];
|
||||||
|
res.data.forEach((item, index) => {
|
||||||
|
if (item.type == 'PLC_GATEWAY') {
|
||||||
|
this.plcInfo = {
|
||||||
|
name: 'PLC网关',
|
||||||
|
status: item.online
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
item.buttonShowType = false;
|
||||||
|
item.typeName = this.typeList.find(el => el.value == item.type).label;
|
||||||
|
if (item.vrDeviceCode) {
|
||||||
|
item.vrDeviceName = this.$store.getters['map/getDeviceByCode'](item.vrDeviceCode).name;
|
||||||
|
}
|
||||||
|
if (this.project == 'heb' || this.project == 'designheb') {
|
||||||
|
if (item.type == 'SWITCH') {
|
||||||
|
this.tableData.push(item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.tableData.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doClose() {
|
||||||
|
this.show = false;
|
||||||
|
},
|
||||||
|
handleClick(row, index) {
|
||||||
|
row.buttonShowType = !row.buttonShowType;
|
||||||
|
this.index = index;
|
||||||
|
this.tableData.splice(index, 1, row);
|
||||||
|
this.$store.dispatch('map/selectDeviceCode', {flag: row.buttonShowType, type: row.type});
|
||||||
|
},
|
||||||
|
async connect(row) {
|
||||||
|
this.$confirm(`您确定连接${this.typeObj[this.selected._type] || '设备'}: ${this.selected.name}, 是否继续?`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const res = await postSimulationConnectById(this.group, row.id, this.selected.code);
|
||||||
|
if (res && res.code == 200) {
|
||||||
|
this.$message.success('连接成功!');
|
||||||
|
this.tableData[this.index]['vrDeviceCode'] = this.selected.code;
|
||||||
|
this.tableData[this.index]['vrDeviceName'] = this.selected.name;
|
||||||
|
this.tableData.splice(this.index, 1, this.tableData[this.index]);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async cancel(row, index) {
|
||||||
|
this.$confirm('您确定将次设备断开, 是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
if (row.vrDeviceCode) {
|
||||||
|
row.vrDeviceCode = '';
|
||||||
|
row.vrDeviceName = '';
|
||||||
|
this.tableData.splice(index, 1, row);
|
||||||
|
try {
|
||||||
|
const res = await putSimulationDisconnectById(this.group, row.id);
|
||||||
|
if (res && res.code == 200) {
|
||||||
|
this.$message.success('断开成功!');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.plc_box{
|
||||||
|
float: left;
|
||||||
|
margin-right: 40px;
|
||||||
|
padding: 9px;
|
||||||
|
}
|
||||||
|
.freshen_box{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.flex_box{
|
||||||
|
float: left;
|
||||||
|
margin-right: 5px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
/deep/ {
|
||||||
|
.el-dialog__wrapper{
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
.dialog_box{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.el-dialog__body{
|
||||||
|
padding-top: 6px;
|
||||||
|
height: calc(100% - 54px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
600
src/views/newMap/displayCity/demon/faultChoose.vue
Normal file
600
src/views/newMap/displayCity/demon/faultChoose.vue
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="dialogShow" id="faultChoose">
|
||||||
|
<div class="falutChooseTitle">{{ title }}</div>
|
||||||
|
<div class="closeFalutChoose" @click="closeFaultChoose">
|
||||||
|
<span class="el-icon-close closeFalutChooseIn" />
|
||||||
|
</div>
|
||||||
|
<el-card class="triggerFaultInfo">
|
||||||
|
<el-button type="primary" size="small" style="margin-bottom:10px;" @click="isTableShow=!isTableShow">{{ isTableShow?'隐藏列表':'显示列表' }}</el-button>
|
||||||
|
<el-table v-if="isTableShow" :data="faultList" height="300" border style="width: 100%;font-size:13px;">
|
||||||
|
<el-table-column prop="targetDeviceCode" label="目标设备" width="220">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ `${deviceMap[scope.row.targetDeviceType]}${formatNameByCode(scope.row.targetDeviceCode)}` }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="faultType" label="故障类型">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ covertFaultType(scope.row) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="condition" label="列车" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ `${deviceMap[scope.row.condition.triggerDeviceType] || ''}${formatNameByCode(scope.row.condition.triggerDeviceCode)}` }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="condition" label="到达区段" width="180">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ `${formatNameByCode(scope.row.condition.triggerAssociatedDeviceCode)}` }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="condition.condition.triggerTime" label="触发时间" width="150" />
|
||||||
|
<el-table-column prop="triggeringTime" label="故障状态">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.triggeringTime? '已触发': '未触发' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button v-if="!scope.row.triggeringTime" type="text" size="small" @click="handleDelete(scope.row)">取消</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
<div class="targetCard">
|
||||||
|
<div class="targetCardHead">
|
||||||
|
<el-button style="padding:3px 0" type="text" @click="addRulesCreate">新增</el-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form ref="form" :model="faultRule" :inline="true" label-width="100px" style="margin-left:15px;">
|
||||||
|
<el-form-item label="目标设备" class="targetFormItem">
|
||||||
|
<el-input v-model="targetDeviceName" disabled size="small" class="inputModelClass" style="width: 300px;" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="故障类型" class="targetFormItem">
|
||||||
|
<el-select v-model="faultRule.faultType" placeholder="请选择" class="inputModelClass" size="small" style="width: 300px;">
|
||||||
|
<el-option
|
||||||
|
v-for="item in faultTypeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'DEVICE'" label="列车" class="targetFormItem">
|
||||||
|
<el-input v-model="triggerDevice" size="small" disabled class="inputModelClass" style="width: 240px;" />
|
||||||
|
<el-button :type="field === 'triggerActive' ? 'danger' : 'primary'" size="small" @click="hover('triggerActive')">{{ $t('map.activate') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'DEVICE'" label="到达区段" class="targetFormItem">
|
||||||
|
<el-input v-model="triggerAssociatedDevice" size="small" disabled class="inputModelClass" style="width: 240px;" />
|
||||||
|
<el-button :type="field === 'triggerAssociated'? 'danger': 'primary'" size="small" @click="hover('triggerAssociated')">{{ $t('map.activate') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="triggerMode === 'TIME'" label="触发时间" class="targetFormItem">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="faultRule.condition.triggerTime"
|
||||||
|
size="small"
|
||||||
|
format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
type="datetime"
|
||||||
|
placeholder="选择日期时间"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getSimulationFaultRules, setFailureModeNew, deleteFailureRule, cancelFailureModeNew } from '@/api/simulation';
|
||||||
|
import ConstConfig from '@/scripts/ConstConfig';
|
||||||
|
import { FaultStatusEnum } from '@/scripts/FaultDicNew';
|
||||||
|
import ModelType from '@/jmapNew/constant/deviceType';
|
||||||
|
import { deviceFaultType } from '@/scripts/cmdPlugin/Config';
|
||||||
|
|
||||||
|
// 故障列表
|
||||||
|
export default {
|
||||||
|
name: 'FaultChoose',
|
||||||
|
props: {
|
||||||
|
group: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
offset: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogShow: false,
|
||||||
|
loading: false,
|
||||||
|
isAdd:false,
|
||||||
|
isTableShow:true,
|
||||||
|
deviceMap: {},
|
||||||
|
simulationFault:{},
|
||||||
|
faultList: [],
|
||||||
|
faultRule:{
|
||||||
|
targetDeviceCode:'',
|
||||||
|
targetDeviceType:'',
|
||||||
|
faultType:'',
|
||||||
|
condition:{
|
||||||
|
triggerDeviceCode:'',
|
||||||
|
triggerDeviceStatus:'',
|
||||||
|
triggerDeviceType :'',
|
||||||
|
type:'DEVICE',
|
||||||
|
triggerTime: '',
|
||||||
|
triggerAssociatedDeviceCode: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
triggerDevice:'',
|
||||||
|
triggerAssociatedDevice: '',
|
||||||
|
triggerMode: 'DEVICE',
|
||||||
|
triggerModeList: [
|
||||||
|
{label: '设备触发', value: 'DEVICE'},
|
||||||
|
{label: '时间触发', value: 'TIME'}
|
||||||
|
],
|
||||||
|
field:'',
|
||||||
|
triggerStatusList:[],
|
||||||
|
faultTypeList:[],
|
||||||
|
targetDeviceName: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
title() {
|
||||||
|
return '自动故障设置';
|
||||||
|
},
|
||||||
|
lineCode() {
|
||||||
|
return this.$route.query.lineCode;
|
||||||
|
},
|
||||||
|
targetDevice() {
|
||||||
|
return this.$store.state.training.triggerFaultDevice;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
'$store.state.socket.autoFaultTrigger':function(val) {
|
||||||
|
this.dialogShow && this.getSimulationFaultRules();
|
||||||
|
},
|
||||||
|
'$store.state.menuOperation.selectedCount':function(em) {
|
||||||
|
const device = this.$store.state.menuOperation.selected;
|
||||||
|
if (device && device.code) {
|
||||||
|
this.deviceSelect(device);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
targetDevice: function(device) {
|
||||||
|
this.targetDeviceName = this.targetDevice.name || this.targetDevice.code;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.deviceMap = [];
|
||||||
|
ConstConfig.ConstSelect.simulationDeviceList.forEach(elem => {
|
||||||
|
this.deviceMap[elem.value] = elem.label;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatNameByCode(code) {
|
||||||
|
let name = '';
|
||||||
|
const device = this.$store.getters['map/getDeviceByCode'](code);
|
||||||
|
if (device) {
|
||||||
|
switch (device._type) {
|
||||||
|
case ModelType.Signal:
|
||||||
|
case ModelType.Switch:
|
||||||
|
case ModelType.Station:
|
||||||
|
case ModelType.Section: {
|
||||||
|
if (device.parentName) {
|
||||||
|
name += device.parentName + '-' + device.name;
|
||||||
|
} else {
|
||||||
|
name += device.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ModelType.Train:
|
||||||
|
name = device.code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (device.stationCode) {
|
||||||
|
const station = this.$store.getters['map/getDeviceByCode'](device.stationCode);
|
||||||
|
if (station) {
|
||||||
|
name += '【' + station.name + '】';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
},
|
||||||
|
hover(field) {
|
||||||
|
if (this.field == '') {
|
||||||
|
this.field = field;
|
||||||
|
} else {
|
||||||
|
this.field = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleDelete(row) {
|
||||||
|
cancelFailureModeNew(row.id, this.$route.query.group).then(resp => {
|
||||||
|
this.getSimulationFaultRules();
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.error('取消故障失败!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
covertType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'SECTION':return 'Section';
|
||||||
|
case 'SIGNAL':return 'Signal';
|
||||||
|
case 'SWITCH':return 'Switch';
|
||||||
|
case 'STATION':return 'Station';
|
||||||
|
case 'ZC':return 'ZcControl';
|
||||||
|
case 'STAND':return 'StationStand';
|
||||||
|
case 'TRAIN':return 'Train';
|
||||||
|
case 'Section':return 'SECTION';
|
||||||
|
case 'Signal':return 'SIGNAL';
|
||||||
|
case 'Switch':return 'SWITCH';
|
||||||
|
case 'Station':return 'STATION';
|
||||||
|
case 'ZcControl':return 'ZC';
|
||||||
|
case 'StationStand':return 'STAND';
|
||||||
|
case 'Train':return 'TRAIN';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
covertFaultType(row) {
|
||||||
|
let faultType = '';
|
||||||
|
if (row && row.id) {
|
||||||
|
let type = this.covertType(row.targetDeviceType);
|
||||||
|
if (type == 'Station') {
|
||||||
|
type = 'ZcControl';
|
||||||
|
}
|
||||||
|
const currentList = deviceFaultType[type];
|
||||||
|
currentList.forEach(temp=>{
|
||||||
|
if (temp.value === row.faultType) {
|
||||||
|
faultType = temp.label;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return faultType;
|
||||||
|
},
|
||||||
|
closeFaultChoose() {
|
||||||
|
this.dialogShow = false;
|
||||||
|
this.isAdd = false;
|
||||||
|
if (this.$refs.addFault) {
|
||||||
|
this.$refs.addFault.resetForm();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeAddRules() {
|
||||||
|
this.isAdd = false;
|
||||||
|
},
|
||||||
|
getSimulationFaultRules() {
|
||||||
|
if (this.dialogShow) {
|
||||||
|
getSimulationFaultRules(this.$route.query.group).then(resp => {
|
||||||
|
this.faultList = resp.data;
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox('获取数据异常');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeTriggerMode(val) {
|
||||||
|
this.resetForm();
|
||||||
|
this.triggerMode = val;
|
||||||
|
this.faultRule.condition.type = val;
|
||||||
|
},
|
||||||
|
doShow() {
|
||||||
|
this.dialogShow = true;
|
||||||
|
this.getSimulationFaultRules();
|
||||||
|
this.resetForm();
|
||||||
|
this.faultTypeList = deviceFaultType[this.targetDevice._type];
|
||||||
|
this.faultRule.targetDeviceCode = this.targetDevice.code;
|
||||||
|
this.faultRule.targetDeviceType = this.covertType(this.targetDevice._type);
|
||||||
|
this.faultRule.faultType = (this.faultTypeList[0] || {}).value;
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.dragEvent();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetForm() {
|
||||||
|
this.getSimulationFaultRules();
|
||||||
|
this.field = '';
|
||||||
|
this.triggerDevice = '';
|
||||||
|
this.triggerAssociatedDevice = '';
|
||||||
|
this.faultRule = {
|
||||||
|
targetDeviceCode:this.targetDevice.code,
|
||||||
|
targetDeviceType:this.covertType(this.targetDevice._type),
|
||||||
|
faultType:'',
|
||||||
|
condition:{
|
||||||
|
triggerDeviceCode:'',
|
||||||
|
triggerDeviceStatus:'',
|
||||||
|
triggerDeviceType :'',
|
||||||
|
type:'DEVICE',
|
||||||
|
triggerTime: '',
|
||||||
|
triggerAssociatedDeviceCode: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
doClose() {
|
||||||
|
this.dialogShow = false;
|
||||||
|
},
|
||||||
|
handleAdd() {
|
||||||
|
this.isAdd = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.addFault.initValue();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteFailure(index, row) {
|
||||||
|
event.cancelBubble = true;
|
||||||
|
this.$confirm('删除故障规则,是否继续?', '提 示', {
|
||||||
|
confirmButtonText: '确 定',
|
||||||
|
cancelButtonText: '取 消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
deleteFailureRule(row.id).then(resp => {
|
||||||
|
}).catch(error => {
|
||||||
|
this.$message.error(`删除故障规则失败: ${error.message}`);
|
||||||
|
});
|
||||||
|
}).catch( () => { });
|
||||||
|
},
|
||||||
|
settingFailure(index, row, idx) {
|
||||||
|
const faultModel = {ruleId: row.id, auto:true};
|
||||||
|
// row['loading' + idx] = true;
|
||||||
|
setFailureModeNew(faultModel, this.group).then(() => {
|
||||||
|
this.getSimulationFaultRules();
|
||||||
|
this.$message.success('设置自动故障成功');
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox('设置自动故障失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancleAutoFault() {
|
||||||
|
const faultModel = {auto:false};
|
||||||
|
setFailureModeNew(faultModel, this.group).then(() => {
|
||||||
|
this.getSimulationFaultRules();
|
||||||
|
this.$message.success('取消自动故障成功');
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox('取消自动故障失败');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addRulesCreate() {
|
||||||
|
if (this.triggerMode === 'DEVICE' && this.triggerDevice == '') {
|
||||||
|
this.$messageBox('请选择触发设备');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.triggerMode === 'DEVICE' && this.faultRule.condition.triggerDeviceStatus == '') {
|
||||||
|
this.$messageBox('请选择触发状态');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.faultRule.faultType == '') {
|
||||||
|
this.$messageBox('请选择故障类型');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.triggerMode === 'TIME' && this.faultRule.condition.triggerTime == '') {
|
||||||
|
this.$messageBox('请选择触发时间');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.triggerMode === 'DEVICE' && this.faultRule.condition.triggerDeviceType === 'TRAIN' && this.faultRule.condition.triggerDeviceStatus === 'Section' && this.faultRule.condition.triggerAssociatedDeviceCode == '') {
|
||||||
|
this.$messageBox('请选择关联设备');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const param = {
|
||||||
|
targetDeviceCode:this.targetDevice.code,
|
||||||
|
targetDeviceType:this.covertType(this.targetDevice._type),
|
||||||
|
faultType: this.faultRule.faultType,
|
||||||
|
condition:{
|
||||||
|
triggerDeviceCode: this.faultRule.condition.triggerDeviceCode || null,
|
||||||
|
triggerDeviceStatus:this.faultRule.condition.triggerDeviceStatus || null,
|
||||||
|
triggerDeviceType :this.faultRule.condition.triggerDeviceType || null,
|
||||||
|
type:this.faultRule.condition.type,
|
||||||
|
triggerTime: this.faultRule.condition.triggerTime || null,
|
||||||
|
triggerAssociatedDeviceCode: this.faultRule.condition.triggerAssociatedDeviceCode || null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setFailureModeNew(param, this.$route.query.group).then(res=>{
|
||||||
|
this.$message.success('创建故障成功!');
|
||||||
|
this.resetForm();
|
||||||
|
}).catch((error)=>{
|
||||||
|
this.$messageBox('创建故障失败: ' + error.message);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deviceSelect(em) {
|
||||||
|
if (this.field.toUpperCase() === 'triggerAssociated'.toUpperCase() && em._type.toUpperCase() === 'Section'.toUpperCase()) {
|
||||||
|
if (em._type.toUpperCase() === 'Section'.toUpperCase() && em.parentName) {
|
||||||
|
this.triggerAssociatedDevice = em._type + '-' + em.parentName + '-' + em.name;
|
||||||
|
} else {
|
||||||
|
this.triggerAssociatedDevice = em._type + '-' + em.name;
|
||||||
|
}
|
||||||
|
this.faultRule.condition.triggerAssociatedDeviceCode = em.code;
|
||||||
|
} else if (this.field.toUpperCase() === 'triggerActive'.toUpperCase() && em._type.toUpperCase() === 'Train'.toUpperCase()) {
|
||||||
|
this.faultRule.condition.triggerDeviceType = this.covertType(em._type);
|
||||||
|
this.faultRule.condition.triggerDeviceCode = em.code;
|
||||||
|
if (em._type.toUpperCase() === 'Section'.toUpperCase() && em.parentName) {
|
||||||
|
this.triggerDevice = em._type + '-' + em.parentName + '-' + em.name;
|
||||||
|
} else if (em._type.toUpperCase() === 'Train'.toUpperCase()) {
|
||||||
|
this.triggerDevice = em._type + '-' + em.code;
|
||||||
|
} else {
|
||||||
|
this.triggerDevice = em._type + '-' + em.name;
|
||||||
|
}
|
||||||
|
this.triggerStatusList = [];
|
||||||
|
const faultStatus = FaultStatusEnum[this.faultRule.condition.triggerDeviceType];
|
||||||
|
if (faultStatus) {
|
||||||
|
const list = Object.keys(faultStatus);
|
||||||
|
list.forEach(key=>{
|
||||||
|
this.triggerStatusList.push({label:faultStatus[key], value:key});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.field = '';
|
||||||
|
this.faultRule.condition.triggerDeviceStatus = (this.triggerStatusList[0] || {}).value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dragEvent() {
|
||||||
|
const offset = this.offset;
|
||||||
|
const dialogHeaderEl = document.querySelector('.falutChooseTitle');
|
||||||
|
const dragDom = document.querySelector('#faultChoose');
|
||||||
|
dialogHeaderEl.style.cursor = 'move';
|
||||||
|
|
||||||
|
/** 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);*/
|
||||||
|
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
|
||||||
|
|
||||||
|
dialogHeaderEl.onmousedown = (e) => {
|
||||||
|
/** 鼠标按下,计算当前元素距离可视区的距离*/
|
||||||
|
const disX = e.clientX - dialogHeaderEl.offsetLeft;
|
||||||
|
const disY = e.clientY - dialogHeaderEl.offsetTop;
|
||||||
|
|
||||||
|
/** 获取到的值带px 正则匹配替换*/
|
||||||
|
let styL, styT;
|
||||||
|
|
||||||
|
/** 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px*/
|
||||||
|
if (sty.left.includes('%')) {
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
|
||||||
|
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
styL = +sty.left.replace(/\px/g, '');
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
styT = +sty.top.replace(/\px/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmousemove = function (e) {
|
||||||
|
/** 通过事件委托,计算移动的距离*/
|
||||||
|
const l = e.clientX - disX;
|
||||||
|
const t = e.clientY - disY;
|
||||||
|
|
||||||
|
/** 移动当前元素*/
|
||||||
|
// dragDom.style.left = `${l + styL}px`;
|
||||||
|
// dragDom.style.top = `${t + styT}px`;
|
||||||
|
|
||||||
|
/** 移动当前元素*/
|
||||||
|
if (l + styL < 0) {
|
||||||
|
dragDom.style.left = `0px`;
|
||||||
|
} else if (l + styL > document.body.clientWidth - dragDom.clientWidth - 10) {
|
||||||
|
dragDom.style.left = `${document.body.clientWidth - dragDom.clientWidth - 10}px`;
|
||||||
|
} else {
|
||||||
|
dragDom.style.left = `${l + styL}px`;
|
||||||
|
}
|
||||||
|
if (t + styT <= offset) {
|
||||||
|
dragDom.style.top = offset + `px`;
|
||||||
|
} else if (t + styT > document.body.clientHeight - dragDom.clientHeight - 10) {
|
||||||
|
dragDom.style.top = `${document.body.clientHeight - dragDom.clientHeight - 10}px`;
|
||||||
|
} else {
|
||||||
|
dragDom.style.top = `${t + styT}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 将此时的位置传出去*/
|
||||||
|
// binding.value({ x: e.pageX, y: e.pageY });
|
||||||
|
};
|
||||||
|
|
||||||
|
document.onmouseup = function () {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
#faultChoose .card .queryList .el-card .el-card__body .el-table--border .el-table__body-wrapper{
|
||||||
|
height: 135px !important;
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
|
#faultChoose .el-button--mini {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.triggerFaultListLeft{
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
width: 730px;
|
||||||
|
}
|
||||||
|
// 谷歌、safari、qq浏览器、360浏览器滚动条样式
|
||||||
|
// 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸
|
||||||
|
#faultChoose .el-table__body-wrapper::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
// height: 110px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
/*定义滚动条轨道 内阴影+圆角*/
|
||||||
|
#faultChoose .el-table__body-wrapper::-webkit-scrollbar-track {
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #FFFFFF;;
|
||||||
|
}
|
||||||
|
/*定义滑块 内阴影+圆角*/
|
||||||
|
#faultChoose .el-table__body-wrapper::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
// box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
/*滑块效果*/
|
||||||
|
#faultChoose .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
|
||||||
|
border-radius: 5px;
|
||||||
|
// box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||||
|
background: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
/*IE滚动条颜色*/
|
||||||
|
html {
|
||||||
|
scrollbar-face-color:#bfbfbf;/*滚动条颜色*/
|
||||||
|
scrollbar-highlight-color:#000;
|
||||||
|
scrollbar-3dlight-color:#000;
|
||||||
|
scrollbar-darkshadow-color:#000;
|
||||||
|
scrollbar-Shadow-color:#adadad;/*滑块边色*/
|
||||||
|
scrollbar-arrow-color:rgba(0,0,0,0.4);/*箭头颜色*/
|
||||||
|
scrollbar-track-color:#eeeeee;/*背景颜色*/
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped rel="stylesheet/scss" lang="scss">
|
||||||
|
.triggerFaultInfo{
|
||||||
|
margin-bottom:10px;
|
||||||
|
padding: 10px 10px 10px 15px;
|
||||||
|
}
|
||||||
|
.triggerFaultList{
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
.triggerFaultTitle{
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.falutChooseTitle{
|
||||||
|
padding: 15px;
|
||||||
|
cursor: all-scroll;
|
||||||
|
}
|
||||||
|
#faultChoose{
|
||||||
|
width: 1000px;
|
||||||
|
position: absolute;
|
||||||
|
left: 30%;
|
||||||
|
top: 20%;
|
||||||
|
background: #fff;
|
||||||
|
padding:0px 0px 15px 0px;
|
||||||
|
// transform: translate3d(-50%,-50%,0);
|
||||||
|
border-radius: 6px;
|
||||||
|
z-index:999;
|
||||||
|
}
|
||||||
|
.faultChooseFoot{
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.closeFalutChoose{
|
||||||
|
position: absolute;
|
||||||
|
right: 0px;
|
||||||
|
top: 0px;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.closeFalutChooseIn{
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.targetCard{
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||||
|
border-top: 1px #ebeef5 solid;
|
||||||
|
}
|
||||||
|
.targetFormItem{
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.targetCardHead{
|
||||||
|
padding: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-bottom: 1px #f4f4f4 solid;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
118
src/views/newMap/displayCity/demon/setTime.vue
Normal file
118
src/views/newMap/displayCity/demon/setTime.vue
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-dialogDrag :title="title" :visible.sync="show" width="550px" :before-close="doClose">
|
||||||
|
<el-form ref="form" label-width="120px" :model="formModel" :rules="rules">
|
||||||
|
<el-form-item :label="$t('display.setTime.systemTime')" prop="initTime">
|
||||||
|
<el-time-picker
|
||||||
|
v-model="formModel.initTime"
|
||||||
|
:picker-options="pickerOptions"
|
||||||
|
:placeholder="$t('display.setTime.anyTime')"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="hasNumber" :label="$t('display.setTime.loadTrainNum')" prop="loadNum">
|
||||||
|
<el-input-number v-model="formModel.loadNum" :min="1" :max="maxNumber" :label="$t('display.setTime.selectLoadTrainNum')" />
|
||||||
|
<span> {{ ` (${$t('display.setTime.maxTrainNum')} :${maxNumber}) ` }} </span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="show = false">{{ $t('global.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" :loading="status" @click="handleSure">{{ $t('global.confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { prefixIntrger } from '@/utils/date';
|
||||||
|
import { getLoadTrainNumber } from '@/api/simulation';
|
||||||
|
|
||||||
|
// 计划行车时间选择
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
formModel: {
|
||||||
|
initTime: new Date(),
|
||||||
|
loadNum: 1
|
||||||
|
},
|
||||||
|
maxNumber: 1,
|
||||||
|
pickerOptions: { selectableRange: '00:00:00 - 23:59:59' },
|
||||||
|
status: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
title() {
|
||||||
|
return this.$t('display.setTime.setSimulationSystemTime');
|
||||||
|
},
|
||||||
|
hasNumber() {
|
||||||
|
return this.$route.params.mode == 'demon' && this.$route.query.prdType == '04';
|
||||||
|
},
|
||||||
|
group() {
|
||||||
|
return this.$route.query.group;
|
||||||
|
},
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
initTime: [
|
||||||
|
{ required: true, message: this.$t('display.setTime.selectSystemTime'), trigger: 'change' },
|
||||||
|
{
|
||||||
|
validator(rule, value, callback) {
|
||||||
|
if (this.maxNumber == 0) {
|
||||||
|
callback(new Error(this.$t('display.setTime.selectValidStartTime')));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'change',
|
||||||
|
maxNumber: this.maxNumber
|
||||||
|
}
|
||||||
|
],
|
||||||
|
loadNum: [
|
||||||
|
{ required: true, message: this.$t('display.setTime.selectTrainNum'), trigger: 'change' }
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doShow() {
|
||||||
|
this.formModel.initTime = new Date(this.$store.state.training.initTime || null);
|
||||||
|
this.handleChange(this.formModel.initTime);
|
||||||
|
this.show = true;
|
||||||
|
},
|
||||||
|
doClose() {
|
||||||
|
this.status = false;
|
||||||
|
this.show = false;
|
||||||
|
},
|
||||||
|
handleChange(initTime) {
|
||||||
|
this.formModel.loadNum = 0;
|
||||||
|
if (this.hasNumber) {
|
||||||
|
getLoadTrainNumber({ time: this.formatTime(initTime) }, this.group).then(resp => {
|
||||||
|
this.maxNumber = parseInt(resp.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatTime(initTime) {
|
||||||
|
const hh = prefixIntrger(initTime.getHours(), 2);
|
||||||
|
const mm = prefixIntrger(initTime.getMinutes(), 2);
|
||||||
|
const ss = prefixIntrger(initTime.getSeconds(), 2);
|
||||||
|
return `${hh}:${mm}:${ss}`;
|
||||||
|
},
|
||||||
|
handleSure() {
|
||||||
|
this.$refs.form.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.status = true;
|
||||||
|
const model = {
|
||||||
|
initTime: this.formatTime(this.formModel.initTime)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.hasNumber) {
|
||||||
|
model['loadNum'] = this.formModel.loadNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('ConfirmSelectBeginTime', model);
|
||||||
|
this.doClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
190
src/views/newMap/displayCity/demonMenu.vue
Normal file
190
src/views/newMap/displayCity/demonMenu.vue
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="isAllShow&&project != 'bjd'" class="display_top_draft" :style="allStyle">
|
||||||
|
<div class="btn_hover" @click="menuClick">菜单</div>
|
||||||
|
<el-button-group ref="button_group_box" class="button_group_box" :style="`margin-left:-${btnWidth}px`">
|
||||||
|
<el-button v-if="jl3dmodelShow && !isContest && project !== 'bjd'" size="small" @click="jumpjlmap3dmodel">{{ jl3dmodel }}</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</div>
|
||||||
|
<Jl3d-Device
|
||||||
|
v-if="deviceif"
|
||||||
|
v-show="deviceShow"
|
||||||
|
ref="Jl3dDevice"
|
||||||
|
:panel-show="deviceShow"
|
||||||
|
@closedevice3dview="jumpjlmap3dmodel"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Jl3dDevice from '@/views/jlmap3d/device/jl3ddevice';
|
||||||
|
import { getToken } from '@/utils/auth';
|
||||||
|
import { getSessionStorage } from '@/utils/auth';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
import { getPostByProjectCode } from '@/api/learn';
|
||||||
|
import { ProjectCode } from '@/scripts/ProjectConfig';
|
||||||
|
export default {
|
||||||
|
name:'DemonMenu',
|
||||||
|
components:{
|
||||||
|
Jl3dDevice,
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
isAllShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
jl3dmodelShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
jl3dnameShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
cctvShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
trafficplanShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
traffictrainShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
scheduleLoadShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
driverShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
schedulePreviewShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
jlmap3dFaultShow:{
|
||||||
|
type:Boolean,
|
||||||
|
require:true
|
||||||
|
},
|
||||||
|
allStyle:{
|
||||||
|
type:String,
|
||||||
|
default() {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hoverBtn: false,
|
||||||
|
btnWidth: 0,
|
||||||
|
group:'',
|
||||||
|
mapId:'',
|
||||||
|
lineCode:'',
|
||||||
|
practiceDisabled:false,
|
||||||
|
deviceif:false,
|
||||||
|
deviceShow: true,
|
||||||
|
drivingShow: false,
|
||||||
|
messageBoard: false,
|
||||||
|
jl3dtrafficplan:this.$t('display.demon.trafficplantext'),
|
||||||
|
jl3dtraffictrain:this.$t('display.demon.traffictraintext'),
|
||||||
|
jl3dpassflow:this.$t('display.demon.passengerflow'),
|
||||||
|
jl3dname: this.$t('display.demon.threeDimensionalView'),
|
||||||
|
jl3dmodel: this.$t('display.demon.deviceView')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
isDrive() {
|
||||||
|
return this.$route.query.prdType == '04';
|
||||||
|
},
|
||||||
|
project() {
|
||||||
|
return getSessionStorage('project');
|
||||||
|
},
|
||||||
|
isContest() {
|
||||||
|
return this.$route.params.mode === 'demon' && this.project == 'drts';
|
||||||
|
},
|
||||||
|
running() {
|
||||||
|
return this.$store.state.training.started;
|
||||||
|
},
|
||||||
|
isLocal() { // 是否为本地项目
|
||||||
|
return process.env.VUE_APP_PRO === 'local';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.group = this.$route.query.group;
|
||||||
|
this.mapId = this.$route.query.mapId;
|
||||||
|
this.lineCode = this.$route.query.lineCode;
|
||||||
|
EventBus.$on('loadScene', () => {
|
||||||
|
this.practiceDisabled = true;
|
||||||
|
});
|
||||||
|
EventBus.$on('quitScene', () => {
|
||||||
|
this.practiceDisabled = false;
|
||||||
|
});
|
||||||
|
if (this.project) {
|
||||||
|
getPostByProjectCode(ProjectCode[this.project]).then(resp => {
|
||||||
|
if (resp.data) {
|
||||||
|
this.messageBoard = true;
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('获取留言板信息失败');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
menuClick() {
|
||||||
|
this.hoverBtn = !this.hoverBtn;
|
||||||
|
if (this.hoverBtn) {
|
||||||
|
this.btnWidth = 600;
|
||||||
|
} else {
|
||||||
|
this.btnWidth = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jumpjlmap3dmodel() {
|
||||||
|
if (this.deviceif == false) {
|
||||||
|
this.deviceif = true;
|
||||||
|
} else {
|
||||||
|
if (this.deviceShow == false) {
|
||||||
|
this.deviceShow = true;
|
||||||
|
} else {
|
||||||
|
this.deviceShow = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.display_top_draft{
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
top: 15px;
|
||||||
|
height: 32px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-left: 44px;
|
||||||
|
z-index: 35;
|
||||||
|
.btn_hover{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
color: #4e4d4d;
|
||||||
|
font-size: 14px;
|
||||||
|
background: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
float: left;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
.button_group_box{
|
||||||
|
float: left;
|
||||||
|
transition: all 0.5s;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-left: -700px;
|
||||||
|
// transform: translateX(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
307
src/views/newMap/displayCity/index.vue
Normal file
307
src/views/newMap/displayCity/index.vue
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
<template>
|
||||||
|
<div class="main" :style="{width: canvasWidth+'px',height:'100%',position:'absolute',overflow:'hidden'}">
|
||||||
|
<template>
|
||||||
|
<transition name="el-zoom-in-bottom">
|
||||||
|
<map-system-draft ref="mapCanvas" @back="back" />
|
||||||
|
</transition>
|
||||||
|
<menu-demon v-if="isDemon" ref="menuDemon" :offset="offset" :offset-bottom="offsetBottom" :data-error="dataError" :text-status-height="textStatusHeight" @start="start" @end="end" />
|
||||||
|
</template>
|
||||||
|
<menu-system-time ref="menuSystemTime" :offset="offset" :group="group" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getSessionStorage } from '@/utils/auth';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import { OperateMode } from '@/scripts/ConstDic';
|
||||||
|
import { timeFormat } from '@/utils/date';
|
||||||
|
import MapSystemDraft from '@/views/newMap/mapsystemNew/index';
|
||||||
|
import MenuDemon from './menuDemon';
|
||||||
|
import MenuSystemTime from '@/views/newMap/displayCity/menuSystemTime';
|
||||||
|
import { clearSimulation, getSimulationInfoNew, ranAsPlan, exitRunPlan } from '@/api/simulation';
|
||||||
|
import { loadMapDataById } from '@/utils/loaddata';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'DisplayDraft',
|
||||||
|
components: {
|
||||||
|
MapSystemDraft,
|
||||||
|
MenuDemon,
|
||||||
|
MenuSystemTime
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
offset: 15,
|
||||||
|
offsetBottom: 15,
|
||||||
|
tipBottom: 0,
|
||||||
|
textStatusHeight: 0,
|
||||||
|
planRunning:false,
|
||||||
|
dataError: false,
|
||||||
|
group:''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
...mapGetters([
|
||||||
|
'canvasWidth'
|
||||||
|
]),
|
||||||
|
mode() {
|
||||||
|
return this.$route.params.mode;
|
||||||
|
},
|
||||||
|
project() {
|
||||||
|
return getSessionStorage('project');
|
||||||
|
},
|
||||||
|
isDemon() {
|
||||||
|
return this.mode === 'demon' && this.project != 'drts';
|
||||||
|
},
|
||||||
|
isContest() {
|
||||||
|
return this.mode === 'demon' && this.project == 'drts';
|
||||||
|
},
|
||||||
|
isExam() {
|
||||||
|
return this.mode === 'exam';
|
||||||
|
},
|
||||||
|
isLesson() {
|
||||||
|
return (this.mode === 'teach' || this.mode === 'manage');
|
||||||
|
},
|
||||||
|
isScript() {
|
||||||
|
return this.mode === 'script';
|
||||||
|
},
|
||||||
|
mapId() {
|
||||||
|
return this.$route.query.mapId;
|
||||||
|
},
|
||||||
|
width() {
|
||||||
|
return this.$store.state.app.width;
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
return this.$store.state.app.height;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
'$store.state.socket.permissionOver': function () {
|
||||||
|
this.$alert('用户权限已被收回', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
callback: action => {
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 此处代码似乎没什么用,之前从menuSchema复制过来的
|
||||||
|
'$store.state.training.prdType':function(val) {
|
||||||
|
if (val == '01') { this.switchModeInner('01'); } else { this.switchModeInner('02'); }
|
||||||
|
},
|
||||||
|
'$store.state.config.menuBarLoadedCount': function (val) { // menuBar加载完成
|
||||||
|
this.setPosition();
|
||||||
|
},
|
||||||
|
'$store.state.app.windowSizeCount': function() { // 窗口缩放
|
||||||
|
this.setWindowSize();
|
||||||
|
},
|
||||||
|
'$store.state.training.prdType': function (val) { // 根据权限类型计算高度
|
||||||
|
this.setPosition();
|
||||||
|
},
|
||||||
|
'$store.state.map.mapViewLoadedCount': function (val) { // 地图视图加载完成标识 开始加载默认状态
|
||||||
|
if (this.planRunning) {
|
||||||
|
this.$store.dispatch('training/simulationStart');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$route() {
|
||||||
|
if (!this.isLesson && !this.isExam) {
|
||||||
|
this.initLoadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearSimulation(this.group);
|
||||||
|
this.$store.dispatch('training/reset');
|
||||||
|
// this.$store.dispatch('map/mapClear');
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
this.setWindowSize();
|
||||||
|
this.initLoadData();
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
// 结束加载状态
|
||||||
|
endViewLoading(isSuccess) {
|
||||||
|
if (!isSuccess) {
|
||||||
|
this.$store.dispatch('map/mapClear');
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
EventBus.$emit('viewLoading', false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 仿真错误时,被动退出时调用
|
||||||
|
async back() {
|
||||||
|
if (this.isExam) {
|
||||||
|
await this.$refs.menuExam.back();
|
||||||
|
} else if (this.isLesson) {
|
||||||
|
await this.$refs.lessonMenu.back();
|
||||||
|
} else if (this.isDemon) {
|
||||||
|
await this.$refs.menuDemon.back();
|
||||||
|
} else if (this.isScript) {
|
||||||
|
await this.$refs.menuScript.back();
|
||||||
|
} else if (this.isContest) {
|
||||||
|
await this.$refs.menuDispatherContest.back();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 设置各个按钮的定位
|
||||||
|
setPosition() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.offset = 10;
|
||||||
|
this.offsetBottom = 15;
|
||||||
|
const menuBar = document.getElementById('menuBar');
|
||||||
|
const menuTool = document.getElementById('menuTool');
|
||||||
|
const menuBottom = document.getElementById('menuButton');
|
||||||
|
const menuButtonsBox = document.getElementById('menuButtons_box');
|
||||||
|
const textStatus = document.getElementById('textStatus');
|
||||||
|
if (menuBar) {
|
||||||
|
this.offset = (menuBar.offsetHeight || 0) + 15;
|
||||||
|
}
|
||||||
|
if (menuTool) {
|
||||||
|
this.offset = (menuTool.offsetHeight || 0) + 15;
|
||||||
|
}
|
||||||
|
const buttonWidth = this.width - 1200; // B box widht
|
||||||
|
if (menuBottom && buttonWidth < 780) {
|
||||||
|
this.offsetBottom = (menuBottom.offsetHeight || 0) + 15;
|
||||||
|
}
|
||||||
|
if (menuButtonsBox) {
|
||||||
|
this.tipBottom = (menuButtonsBox.offsetHeight || 0) + 15;
|
||||||
|
}
|
||||||
|
if (textStatus) {
|
||||||
|
this.textStatusHeight = textStatus.offsetHeight || 0;
|
||||||
|
textStatus.style.top = this.offset - 15 + 'px';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 缩放设置
|
||||||
|
setWindowSize() {
|
||||||
|
const width = this.width;
|
||||||
|
const height = this.height;
|
||||||
|
this.$store.dispatch('config/resize', { width, height });
|
||||||
|
// this.$store.dispatch('training/updateOffsetStationCode', { offsetStationCode: this.offsetStationCode });
|
||||||
|
},
|
||||||
|
// 初始化
|
||||||
|
initLoadData() {
|
||||||
|
this.group = this.$route.query.group;
|
||||||
|
this.$store.dispatch('training/reset');
|
||||||
|
this.loadSimulationInfo();
|
||||||
|
this.loadMapData();
|
||||||
|
},
|
||||||
|
// 新版地图根据仿真group获取仿真基础信息
|
||||||
|
async loadSimulationInfo() {
|
||||||
|
const resp = await getSimulationInfoNew(this.group);
|
||||||
|
if (resp && resp.code == 200 && resp.data) {
|
||||||
|
if (!resp.data.dataError) {
|
||||||
|
this.$store.dispatch('scriptRecord/updateSimulationPause', resp.data.pause); // 是否暂停判断
|
||||||
|
this.$store.dispatch('training/setInitTime', +new Date(`${new Date().toLocaleDateString()} ${timeFormat(resp.data.systemTime)}`));
|
||||||
|
this.$store.dispatch('training/countTime');
|
||||||
|
this.$store.dispatch('runPlan/setRunPlanInfo', resp.data.runPlan);
|
||||||
|
this.planRunning = resp.data.planRunning;
|
||||||
|
if (resp.data.planRunning) {
|
||||||
|
this.$store.commit('training/start');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$messageBox('此地图数据正在维护中,无法运行!');
|
||||||
|
}
|
||||||
|
this.dataError = resp.data.dataError;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 通过showMode切换显示效果
|
||||||
|
switchModeInner(swch) {
|
||||||
|
let showMode = '03';
|
||||||
|
if (swch == '01') {
|
||||||
|
showMode = '03';
|
||||||
|
} else if (swch == '02') {
|
||||||
|
showMode = '02';
|
||||||
|
}
|
||||||
|
|
||||||
|
const nameList = Object.keys(this.$store.state.map.map || {});
|
||||||
|
let list = [];
|
||||||
|
nameList.forEach(item => {
|
||||||
|
if (item !== 'skinVO') {
|
||||||
|
const data = this.$store.state.map.map[item];
|
||||||
|
if (data && data.constructor === Array) {
|
||||||
|
list = [...list, ...data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (swch == '01') {
|
||||||
|
this.$jlmap.updateShowStation(list, this.$store.state.training.centerStationCode); // 显示全部元素
|
||||||
|
} else {
|
||||||
|
this.$jlmap.updateShowStation(list, ''); // 显示全部元素
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$jlmap.updateShowMode(list, showMode); // 二次过滤
|
||||||
|
},
|
||||||
|
// 加载地图数据
|
||||||
|
loadMapData() {
|
||||||
|
if (parseInt(this.mapId)) {
|
||||||
|
this.$store.dispatch('training/changeOperateMode', { mode: OperateMode.NORMAL }); // 默认为正常模式
|
||||||
|
loadMapDataById(this.mapId, 'simulation');
|
||||||
|
} else {
|
||||||
|
this.endViewLoading();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start(model) { // 开始仿真
|
||||||
|
const data = {
|
||||||
|
time: model.initTime
|
||||||
|
};
|
||||||
|
if (this.$route.query.prdType === '04') {
|
||||||
|
data.loadNumber = model.loadNum;
|
||||||
|
}
|
||||||
|
ranAsPlan(data, this.group).then(res => {
|
||||||
|
this.$store.dispatch('training/setInitTime', +new Date(`${new Date().toLocaleDateString()} ${model.initTime}`));
|
||||||
|
}).catch(error => {
|
||||||
|
let message = '';
|
||||||
|
switch (error.code) {
|
||||||
|
case '5001':
|
||||||
|
message = this.$t('error.mapDataError');
|
||||||
|
break;
|
||||||
|
case '5002':
|
||||||
|
message = this.$t('error.runningChartDataError');
|
||||||
|
break;
|
||||||
|
case '5003':
|
||||||
|
message = this.$t('error.runningChartIsNotLoaded');
|
||||||
|
break;
|
||||||
|
case '5004':
|
||||||
|
message = this.$t('error.runningDataError');
|
||||||
|
break;
|
||||||
|
case '5000':
|
||||||
|
message = this.$t('error.systemError');
|
||||||
|
break;
|
||||||
|
case '4000':
|
||||||
|
message = this.$t('error.simulationDoesNotExist');
|
||||||
|
break;
|
||||||
|
case '4001':
|
||||||
|
message = this.$t('error.simulationOperationIsNotDefined');
|
||||||
|
break;
|
||||||
|
case '4002':
|
||||||
|
message = this.$t('error.simulationOperationProcessingMethodNotFound');
|
||||||
|
break;
|
||||||
|
case '4003':
|
||||||
|
message = this.$t('error.simulationOperationFailed');
|
||||||
|
break;
|
||||||
|
case '4004':
|
||||||
|
message = this.$t('error.operationConflict');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = '按计划行车异常,请退出重试!';
|
||||||
|
// this.$messageBox('按计划行车异常,请退出重试!');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.$messageBox(message + ',' + this.$t('error.startSimulationFailed'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
end() {
|
||||||
|
exitRunPlan(this.group).then(() => {
|
||||||
|
this.$store.dispatch('training/over').then(() => {
|
||||||
|
this.$store.dispatch('training/setMapDefaultState').then(() => {
|
||||||
|
this.$store.dispatch('map/clearJlmapTrainView');
|
||||||
|
this.$store.dispatch('map/resetActiveTrainList', false);
|
||||||
|
this.$store.dispatch('map/setTrainWindowShow', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox(this.$t('display.demon.endSimulationFail'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
306
src/views/newMap/displayCity/menuDemon.vue
Normal file
306
src/views/newMap/displayCity/menuDemon.vue
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<demon-menu
|
||||||
|
ref="demonMenu"
|
||||||
|
:is-all-show="!dataError"
|
||||||
|
:jl3dmodel-show="isShow3dmodel && !isShowScheduling && !isDrive"
|
||||||
|
:jl3dname-show="!isShowScheduling&&!isDrive"
|
||||||
|
:cctv-show="!isShowScheduling"
|
||||||
|
:trafficplan-show="!isShowScheduling"
|
||||||
|
:schedule-load-show="isShowScheduling && !runing"
|
||||||
|
:schedule-preview-show="isShowScheduling && runing"
|
||||||
|
:jlmap3d-fault-show="false"
|
||||||
|
:driver-show="isDrive"
|
||||||
|
:all-style="'top:'+(offset+textStatusHeight)+'px'"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<menu-schema
|
||||||
|
ref="menuSchema"
|
||||||
|
:offset="offset"
|
||||||
|
:data-error="dataError"
|
||||||
|
:offset-bottom="offsetBottom"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="display-draft" :class="{'haerbin_btn_box': $route.query.lineCode == '07'||$route.query.lineCode == '14'}" :style="{bottom: offsetBottom + 'px'}">
|
||||||
|
<el-button-group class="button-group-box">
|
||||||
|
<template v-if="!dataError">
|
||||||
|
<template v-if="!projectDevice">
|
||||||
|
<el-button type="danger" size="small" @click="end">{{ $t('display.demon.initialize') }}</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<el-button v-if="project !='bjd'" type="primary" size="small" @click="back">{{ projectDevice?'退出':$t('display.demon.back') }}</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 单人仿真 -->
|
||||||
|
<script>
|
||||||
|
import DemonMenu from './demonMenu';
|
||||||
|
import { Notification } from 'element-ui';
|
||||||
|
import MenuSchema from '@/views/newMap/displayCity/menuSchema';
|
||||||
|
import { getGoodsTryUse } from '@/api/management/goods';
|
||||||
|
import {getSimulationInfoNew, clearSimulation } from '@/api/simulation';
|
||||||
|
import { PermissionType } from '@/scripts/ConstDic';
|
||||||
|
import { getCountTime } from '@/utils/index';
|
||||||
|
import { TrainingMode } from '@/scripts/ConstDic';
|
||||||
|
import { quitScriptNew } from '@/api/simulation';
|
||||||
|
import { setGoodsTryUse } from '@/api/management/goods';
|
||||||
|
import {loadScriptNew } from '@/api/simulation';
|
||||||
|
import StatusIcon from '@/views/components/StatusIcon/statusIcon';
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { getSessionStorage } from '@/utils/auth';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuDemon',
|
||||||
|
components: {
|
||||||
|
MenuSchema,
|
||||||
|
DemonMenu,
|
||||||
|
StatusIcon
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
offset: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
offsetBottom: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
dataError: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
textStatusHeight: {
|
||||||
|
type: Number,
|
||||||
|
default() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tryTime: 0, // 进入页面多少秒
|
||||||
|
timeNow: 0, // 进入页面 相对时间
|
||||||
|
time: null, // 定时器
|
||||||
|
countTime: 0, // 显示 倒计时
|
||||||
|
remainingTime: 0,
|
||||||
|
userRole:'AUDIENCE',
|
||||||
|
goodsId: this.$route.query.goodsId,
|
||||||
|
try: this.$route.query.try, // 是否是试用权限
|
||||||
|
training: {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
remarks: ''
|
||||||
|
},
|
||||||
|
isScriptRun:false,
|
||||||
|
jl3dname: this.$t('display.demon.threeDimensionalView'),
|
||||||
|
jl3dmodel: this.$t('display.demon.deviceView'),
|
||||||
|
isShow3dmodel :true,
|
||||||
|
isGoback: false,
|
||||||
|
runing:false,
|
||||||
|
prdTypeMap: {
|
||||||
|
'01': '01', // 现地 => 现地
|
||||||
|
'02': '02', // 行调 => 行调
|
||||||
|
'04': '02', // 司机 => 行调
|
||||||
|
'05': '' // 派班 => null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isShowScheduling() {
|
||||||
|
return this.$route.query.prdType == '05';
|
||||||
|
},
|
||||||
|
isDrive() {
|
||||||
|
return this.$route.query.prdType == '04';
|
||||||
|
},
|
||||||
|
group() {
|
||||||
|
return this.$route.query.group;
|
||||||
|
},
|
||||||
|
projectDevice() {
|
||||||
|
return this.$route.query.projectDevice;
|
||||||
|
},
|
||||||
|
project() {
|
||||||
|
return getSessionStorage('project');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.training.subscribeCount': function () {
|
||||||
|
this.group && this.initLoadPage();
|
||||||
|
},
|
||||||
|
'$store.state.socket.simulationRoleList':function(val) {
|
||||||
|
(val || []).forEach(item => {
|
||||||
|
if (item.messageType === 'KICK_OUT' && item.userId == this.$store.state.user.id) {
|
||||||
|
!this.isGoback && this.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'$store.state.socket.simulationOver':function(val) {
|
||||||
|
!this.isGoback && this.back();
|
||||||
|
},
|
||||||
|
'$store.state.socket.simulationStart':function(val) {
|
||||||
|
if (val) {
|
||||||
|
this.setRuning(true);
|
||||||
|
this.$store.dispatch('training/simulationStart').then(() => {
|
||||||
|
this.$store.dispatch('map/setShowCentralizedStationNum');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'$store.state.socket.simulationReset':function(val) {
|
||||||
|
this.setRuning(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$store.dispatch('training/setPrdType', this.$route.query.prdType);
|
||||||
|
switch (this.$store.state.training.prdType) {
|
||||||
|
case '02': { this.userRole = 'DISPATCHER'; break; }
|
||||||
|
case '01': { this.userRole = 'STATION_SUPERVISOR'; break; }
|
||||||
|
case '04': { this.userRole = 'DRIVER'; break; }
|
||||||
|
case '05': { this.userRole = 'DEPOT_DISPATCHER'; break; }
|
||||||
|
default: { this.userRole = 'AUDIENCE'; break; }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.time) {
|
||||||
|
this.setTryTime();
|
||||||
|
clearTimeout(this.time);
|
||||||
|
}
|
||||||
|
this.$store.dispatch('scriptRecord/updateSimulationPause', false);
|
||||||
|
this.$store.dispatch('map/resetActiveTrainList', true);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.dispatch('training/end', TrainingMode.NORMAL);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.demonMenu.menuClick();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async initLoadPage() {
|
||||||
|
try {
|
||||||
|
if (this.try != '0') {
|
||||||
|
this.loadInitData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadInitData() {
|
||||||
|
const data = {
|
||||||
|
mapId: this.$route.query.mapId,
|
||||||
|
prdType: this.$route.query.prdType,
|
||||||
|
permissionType: PermissionType.SIMULATION
|
||||||
|
};
|
||||||
|
getGoodsTryUse(data).then(res => {
|
||||||
|
this.remainingTime = res.data.tryTime;
|
||||||
|
this.timeNow = Date.parse(new Date()) / 1000 + this.remainingTime;
|
||||||
|
if (this.try) {
|
||||||
|
this.time = setInterval(() => {
|
||||||
|
this.tryTime += 1;
|
||||||
|
this.countTime = getCountTime(this.timeNow);
|
||||||
|
if (this.countTime == -1) {
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox(this.$t('display.demon.getTimeFail'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectBeginTime() {
|
||||||
|
this.$refs.setTime.doShow();
|
||||||
|
},
|
||||||
|
start(model) {
|
||||||
|
this.$emit('start', model);
|
||||||
|
},
|
||||||
|
setRuning(run) {
|
||||||
|
this.runing = run;
|
||||||
|
},
|
||||||
|
end() {
|
||||||
|
this.$emit('end');
|
||||||
|
},
|
||||||
|
clearAllData() {
|
||||||
|
this.$refs.chatbox.clearAllData();
|
||||||
|
},
|
||||||
|
async back() {
|
||||||
|
this.isGoback = true;
|
||||||
|
if (this.projectDevice) {
|
||||||
|
clearSimulation(this.group).then(res=>{
|
||||||
|
this.$store.dispatch('training/over').then(() => {
|
||||||
|
this.$store.dispatch('LogOut').then(() => {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (this.project === 'bjd') {
|
||||||
|
window.close();
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('map/setShowCentralizedStationCode', '');
|
||||||
|
history.go(-1);
|
||||||
|
Notification.closeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setTryTime() {
|
||||||
|
if (this.try) {
|
||||||
|
const data = { time: this.tryTime, goodsId: this.goodsId };
|
||||||
|
if (data.goodsId) {
|
||||||
|
setGoodsTryUse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
quit() {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
@import "src/styles/mixin.scss";
|
||||||
|
|
||||||
|
.display-card {
|
||||||
|
z-index: 9;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: 17px;
|
||||||
|
left: 160px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-card .el-row {
|
||||||
|
line-height: 32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-score {
|
||||||
|
background-color: black;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 24px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-left: 2px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-family: "Microsoft" !important;
|
||||||
|
font-size: 18px !important;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.haerbin_btn_box{
|
||||||
|
width: 450px;
|
||||||
|
bottom: 15px!important;
|
||||||
|
}
|
||||||
|
.display-draft {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 15px;
|
||||||
|
.button-group-box{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
111
src/views/newMap/displayCity/menuSchema.vue
Normal file
111
src/views/newMap/displayCity/menuSchema.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="schema" :style="{top: offset+'px'}">
|
||||||
|
<el-button v-if="!isScheduling" size="small" :type="faultMode ? '':'primary' " @click="changeOperateMode()">{{ faultMode?'切换到普通模式[Tab]':'切换到故障模式[Tab]' }}</el-button>
|
||||||
|
<fault-choose ref="faultChoose" :group="group" :offset="offset" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import FaultChoose from './demon/faultChoose';
|
||||||
|
import { OperateMode } from '@/scripts/ConstDic';
|
||||||
|
import { getByGroupStationList } from '@/api/jmap/map';
|
||||||
|
import { getSessionStorage } from '@/utils/auth';
|
||||||
|
import { loadRunPlanData } from '@/utils/loaddata';
|
||||||
|
import { EventBus } from '@/scripts/event-bus';
|
||||||
|
|
||||||
|
// 右上角操作
|
||||||
|
export default {
|
||||||
|
name: 'MenuSchema',
|
||||||
|
components: {
|
||||||
|
FaultChoose
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
offset: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
dataError: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mode: OperateMode.NORMAL,
|
||||||
|
OperateMode: OperateMode,
|
||||||
|
viewDisabled: true,
|
||||||
|
faultMode: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
group() {
|
||||||
|
return this.$route.query.group;
|
||||||
|
},
|
||||||
|
isScript() {
|
||||||
|
return this.$route.params.mode === 'script';
|
||||||
|
},
|
||||||
|
isDemon() {
|
||||||
|
return this.$route.params.mode === 'demon';
|
||||||
|
},
|
||||||
|
isScheduling() {
|
||||||
|
return this.$route.query.prdType === '05';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.training.triggerFaultCount': function () {
|
||||||
|
this.setFault();
|
||||||
|
},
|
||||||
|
'$store.state.runPlan.loadRunPlanCount': function () {
|
||||||
|
this.viewDisabled = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
EventBus.$on('CheckFaultModeEvent', () => {
|
||||||
|
if (!this.isScheduling) {
|
||||||
|
this.changeOperateMode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadRunData() {
|
||||||
|
this.$store.dispatch('runPlan/clear').then(() => {
|
||||||
|
if (this.group) {
|
||||||
|
this.viewDisabled = true;
|
||||||
|
// 获取排序的车站列表
|
||||||
|
getByGroupStationList(this.group).then(response => {
|
||||||
|
this.$store.dispatch('runPlan/setStations', response.data).then(() => {
|
||||||
|
loadRunPlanData(this.group, this.dataError);
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
this.$messageBox(this.$t('display.schema.getStationListFail'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeOperateMode() {
|
||||||
|
this.faultMode = !this.faultMode;
|
||||||
|
let mode = OperateMode.NORMAL;
|
||||||
|
if (this.faultMode) {
|
||||||
|
mode = OperateMode.FAULT;
|
||||||
|
}
|
||||||
|
this.$store.dispatch('training/changeOperateMode', { mode: mode });
|
||||||
|
},
|
||||||
|
setFault() {
|
||||||
|
this.$refs.faultChoose.doShow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.schema {
|
||||||
|
z-index: 36;
|
||||||
|
display: inline;
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-button+.el-button {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
154
src/views/newMap/displayCity/menuSystemTime.vue
Normal file
154
src/views/newMap/displayCity/menuSystemTime.vue
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="isShowSystemTime" class="display-card" :style="{top: top+'px', right: newRight+'px'}">
|
||||||
|
<template v-if="pause">
|
||||||
|
<span class="display-pause">{{ $t('display.systemTime.timePause') }}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<system-time
|
||||||
|
class="display-time"
|
||||||
|
:time="time"
|
||||||
|
/>
|
||||||
|
<div v-if="isShowDate" style="width: 80px;height: 58px;float: right;box-shadow: 0 0 5px #eee;">
|
||||||
|
<div class="display-date-box">{{ dateString }}</div>
|
||||||
|
<div class="display-date-box">{{ dayString }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { prefixIntrger } from '@/utils/date';
|
||||||
|
import SystemTime from '@/views/components/systemTime/index';
|
||||||
|
import { timeFormat } from '@/utils/date';
|
||||||
|
|
||||||
|
// 顶部时间栏显示
|
||||||
|
export default {
|
||||||
|
name: 'MenuSystemTime',
|
||||||
|
components: {
|
||||||
|
SystemTime
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
offset: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
time: '00:0000',
|
||||||
|
dateString: '00/00/00',
|
||||||
|
dayString: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isShowSystemTime() {
|
||||||
|
return this.$route.params.mode == 'demon' ||
|
||||||
|
this.$route.params.mode == 'dp' ||
|
||||||
|
this.$route.params.mode == 'plan' ||
|
||||||
|
this.$route.params.mode == 'script' ||
|
||||||
|
this.$route.params.mode == 'practice' ||
|
||||||
|
!this.$route.params.mode;
|
||||||
|
},
|
||||||
|
pause() {
|
||||||
|
return this.$store.state.scriptRecord.simulationPause;
|
||||||
|
},
|
||||||
|
isDisplay() {
|
||||||
|
return this.$route.path.includes('displayCity') || this.$route.path.includes('scriptdisplayCity');
|
||||||
|
},
|
||||||
|
isShowDate() { // 西安一 三号线
|
||||||
|
return (this.$route.query.lineCode == 10 || this.$route.query.lineCode == 11) && this.isDisplay;
|
||||||
|
},
|
||||||
|
top() {
|
||||||
|
return this.isShowDate ? (this.$route.query.prdType == '05' ? 5 : this.offset - 10) : this.offset;
|
||||||
|
},
|
||||||
|
newRight() {
|
||||||
|
return this.isShowDate ? this.$store.state.config.width - 420 : this.$store.state.config.width / 2 - 55;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.training.initTime': function (initTime) {
|
||||||
|
const date = new Date(initTime);
|
||||||
|
this.initDate(date);
|
||||||
|
},
|
||||||
|
'$store.state.socket.simulationTimeSync': function (time) { // 仿真时间更新
|
||||||
|
this.$store.dispatch('training/setInitTime', +new Date(`${new Date().toLocaleDateString()} ${timeFormat(time)}`));
|
||||||
|
const date = new Date(+new Date(`${new Date().toLocaleDateString()} ${timeFormat(time)}`));
|
||||||
|
this.initDate(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const initTime = this.$store.state.training.initTime;
|
||||||
|
if (initTime > 0) {
|
||||||
|
const date = new Date(initTime);
|
||||||
|
this.initDate(date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initDate(date) {
|
||||||
|
this.time = `${prefixIntrger(date.getHours(), 2)}:${prefixIntrger(date.getMinutes(), 2)}${prefixIntrger(date.getSeconds(), 2)}`;
|
||||||
|
const years = date.getFullYear() + '';
|
||||||
|
let months = date.getMonth() + 1 + '';
|
||||||
|
let dates = date.getDate() + '';
|
||||||
|
if (months.length < 2) { months = '0' + months; }
|
||||||
|
if (dates.length < 2) { dates = '0' + dates; }
|
||||||
|
this.dateString = dates + '/' + months + '/' + years.slice(2);
|
||||||
|
const day = date.getDay();
|
||||||
|
switch (day) {
|
||||||
|
case 0:
|
||||||
|
this.dayString = '星 期 日';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this.dayString = '星 期 一';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.dayString = '星 期 二';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this.dayString = '星 期 三';
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
this.dayString = '星 期 四';
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
this.dayString = '星 期 五';
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
this.dayString = '星 期 六';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
@import "src/styles/mixin.scss";
|
||||||
|
|
||||||
|
.display-card {
|
||||||
|
z-index: 9;
|
||||||
|
display: inline;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-pause {
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-time{
|
||||||
|
padding: 3px 5px;
|
||||||
|
border: 1px solid rgba(255,255,255,.2);
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(255,255,255,.3);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-card .el-row {
|
||||||
|
line-height: 32px !important;
|
||||||
|
}
|
||||||
|
.display-date-box{
|
||||||
|
height: 29px;
|
||||||
|
line-height: 29px;
|
||||||
|
background: #404040;
|
||||||
|
color: #1DEA1E;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
58
src/views/newMap/displayCity/utils.js
Normal file
58
src/views/newMap/displayCity/utils.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import ConstConfig from '@/scripts/ConstConfig';
|
||||||
|
import Cookies from 'js-cookie';
|
||||||
|
import store from '@/store/index';
|
||||||
|
export function covertMemberData (activeTrainList, resp) {
|
||||||
|
let lastData = JSON.stringify(resp);
|
||||||
|
const roleTypeList = ConstConfig.ConstSelect.roleTypeNew;
|
||||||
|
roleTypeList.forEach(function(element) {
|
||||||
|
const rolename = element.value;
|
||||||
|
if (Cookies.get('user_lang') == 'en') {
|
||||||
|
lastData = lastData.replace(new RegExp(rolename, 'g'), element.enLabel);
|
||||||
|
} else {
|
||||||
|
lastData = lastData.replace(new RegExp(rolename, 'g'), element.label);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lastData = JSON.parse(lastData);
|
||||||
|
const lastMemberList = [];
|
||||||
|
// const electricDispatcherList = [];
|
||||||
|
const deviceListData = [[], [], [], [], [], [], [], []];
|
||||||
|
const driverList = [];
|
||||||
|
lastData.forEach((member, index)=>{
|
||||||
|
if (member.userId && member.userId == store.state.user.id) {
|
||||||
|
member.disabled = true;
|
||||||
|
member.userName = store.state.user.nickname;
|
||||||
|
store.dispatch('training/setOrignalUserRoleId', member.id);
|
||||||
|
} else {
|
||||||
|
member.disabled = false;
|
||||||
|
}
|
||||||
|
const userName = member.userName ? '-' + member.userName : '';
|
||||||
|
const name = member.name ? '-' + member.name : '';
|
||||||
|
if (member.deviceCode) {
|
||||||
|
const device = store.getters['map/getDeviceByCode'](member.deviceCode);
|
||||||
|
member.deviceName = device.name || device.groupNumber;
|
||||||
|
member.label = member.type + member.deviceName + name + userName;
|
||||||
|
member.normalName = member.type + member.deviceName + name;
|
||||||
|
} else {
|
||||||
|
member.deviceName = '';
|
||||||
|
member.label = member.type + name + userName;
|
||||||
|
member.normalName = member.type + name;
|
||||||
|
}
|
||||||
|
const deviceType = ['行调', '通号', '行值', '司机', '车辆段信号楼', '上级部门', '电力调度', '停车场信号楼'];
|
||||||
|
const deviceTypeIndex = deviceType.indexOf(member.type);
|
||||||
|
if (deviceTypeIndex >= 0) {
|
||||||
|
if (deviceTypeIndex == 3) {
|
||||||
|
if (activeTrainList.length > 0) {
|
||||||
|
if (activeTrainList.includes(member.deviceCode)) {
|
||||||
|
deviceListData[deviceTypeIndex].push(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastMemberList.push(member);
|
||||||
|
driverList.push(member);
|
||||||
|
} else {
|
||||||
|
deviceListData[deviceTypeIndex].push(member);
|
||||||
|
lastMemberList.push(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {lastMemberList:lastMemberList, deviceListData:deviceListData, driverList:driverList};
|
||||||
|
}
|
373
src/views/newMap/displayNew/demon/runPlanView2.vue
Normal file
373
src/views/newMap/displayNew/demon/runPlanView2.vue
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
<template>
|
||||||
|
<!-- v-dialogDrag -->
|
||||||
|
<el-dialog
|
||||||
|
v-dialogLoading="dialogLoading"
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="dialogShow"
|
||||||
|
width="100%"
|
||||||
|
:before-close="doClose"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:modal="false"
|
||||||
|
fullscreen
|
||||||
|
>
|
||||||
|
<div :id="runPlanId" v-loading="loading" />
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import { getPublishMapInfo } from '@/api/jmap/map';
|
||||||
|
import { timeFormat } from '@/utils/date';
|
||||||
|
import echarts from 'echarts';
|
||||||
|
import {toTimeStamp, formatDuring} from '@/utils/date';
|
||||||
|
|
||||||
|
// 运行图预览
|
||||||
|
export default {
|
||||||
|
name: 'RunPlanView',
|
||||||
|
props: {
|
||||||
|
group: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogShow: false,
|
||||||
|
loading: true,
|
||||||
|
runPlanId: 'run-plan-view',
|
||||||
|
myChart: null,
|
||||||
|
PlanConvert: {},
|
||||||
|
series: [],
|
||||||
|
option: {
|
||||||
|
title: {
|
||||||
|
text: '',
|
||||||
|
left: 'center'
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '30px',
|
||||||
|
left: '120px',
|
||||||
|
right: '40px',
|
||||||
|
bottom: '80px',
|
||||||
|
containLabel: true,
|
||||||
|
backgroundColor: 'floralwhite'
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
// right: '20px',
|
||||||
|
// feature: {
|
||||||
|
// dataZoom: {
|
||||||
|
// yAxisIndex: 'none'
|
||||||
|
// },
|
||||||
|
// restore: {},
|
||||||
|
// saveAsImage: {}
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
axisPointer: {
|
||||||
|
trigger: 'item',
|
||||||
|
type: 'cross'
|
||||||
|
},
|
||||||
|
formatter: this.axisTooltip,
|
||||||
|
borderWidth: 1
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: [],
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: '#d14a61'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
formatter: this.xAxisLableFormat,
|
||||||
|
textStyle: {
|
||||||
|
color: '#333'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisPointer: {
|
||||||
|
snap: true,
|
||||||
|
label: {
|
||||||
|
formatter: this.xAxisPointFormat,
|
||||||
|
backgroundColor: 'rgb(255,0,0,0.5)',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
color: '#d14a61'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
interval: 'auto',
|
||||||
|
formatter: this.yAxisLableFormat
|
||||||
|
},
|
||||||
|
axisPointer: {
|
||||||
|
xAxisIndex: 'all',
|
||||||
|
label: {
|
||||||
|
formatter: this.yAxisPointFormat,
|
||||||
|
backgroundColor: 'rgb(0,100,0,0.5)',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
min: 0,
|
||||||
|
max: 0
|
||||||
|
},
|
||||||
|
// graphic: {
|
||||||
|
// type: 'line',
|
||||||
|
// progressive: true
|
||||||
|
// },
|
||||||
|
series: [],
|
||||||
|
dataZoom: [
|
||||||
|
{
|
||||||
|
type: 'inside'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fiterMode: 'filter',
|
||||||
|
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
|
||||||
|
handleSize: '80%',
|
||||||
|
handleStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
shadowBlur: 3,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.6)',
|
||||||
|
shadowOffsetX: 2,
|
||||||
|
shadowOffsetY: 2
|
||||||
|
},
|
||||||
|
bottom: '25px'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
absoluteTime: 2 * 3600,
|
||||||
|
indexKmRangeMap: {},
|
||||||
|
runPlanData: {},
|
||||||
|
dialogLoading: false,
|
||||||
|
initialPlanData: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('runPlan', [
|
||||||
|
'stations'
|
||||||
|
]),
|
||||||
|
title() {
|
||||||
|
return this.$t('display.runPlan.previewRunDiagram');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.runPlan.planLoadedCount': async function () {
|
||||||
|
try {
|
||||||
|
await this.loadChartPage();
|
||||||
|
if (this.dialogShow) {
|
||||||
|
await this.loadInitData(this.series);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'$store.state.runPlan.planUpdateCount': function () {
|
||||||
|
this.updateRunPlanData(this.$store.state.runPlan.updateData);
|
||||||
|
},
|
||||||
|
'$store.state.app.windowSizeCount': function() {
|
||||||
|
this.reSize({ width: this.$store.state.app.width, height: this.$store.state.app.height - 55 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
getPublishMapInfo(this.$route.query.mapId).then(res=>{
|
||||||
|
this.PlanConvert = this.$theme.loadPlanConvert(res.data.lineCode);
|
||||||
|
this.initialPlanData = this.$store.state.runPlan.planData;
|
||||||
|
this.loadChartPage();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.myChart && this.myChart.isDisposed) {
|
||||||
|
this.myChart.dispose();
|
||||||
|
this.myChart = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async doShow() {
|
||||||
|
try {
|
||||||
|
this.dialogLoading = true;
|
||||||
|
this.dialogShow = true;
|
||||||
|
this.loadInitData(this.series);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
this.dialogLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async doClose() {
|
||||||
|
this.dialogShow = false;
|
||||||
|
},
|
||||||
|
async loadChartPage() {
|
||||||
|
const stations = this.$store.state.runPlan.stations;
|
||||||
|
const planData = this.$store.state.runPlan.planData;
|
||||||
|
this.series = [];
|
||||||
|
this.kmRangeCoordMap = this.PlanConvert.convertStationsToMap(stations);
|
||||||
|
this.pushModels(this.series, [this.PlanConvert.initializeYaxis(stations)]);
|
||||||
|
this.pushModels(this.series, this.PlanConvert.convertDataToModels(planData, stations, this.kmRangeCoordMap, { width: 1, color: '#000' }));
|
||||||
|
},
|
||||||
|
async loadInitData(series) {
|
||||||
|
this.myChart && this.myChart.showLoading();
|
||||||
|
await this.xAxisInit();
|
||||||
|
await this.yAxisInit();
|
||||||
|
await this.loadInitChart(series);
|
||||||
|
this.myChart && this.myChart.hideLoading();
|
||||||
|
},
|
||||||
|
loadInitChart(series) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
if (this.myChart && this.myChart.isDisposed) {
|
||||||
|
this.myChart.clear();
|
||||||
|
}
|
||||||
|
let startValue = 3600 + this.PlanConvert.TranslationTime;
|
||||||
|
const offsetTime = 3600;
|
||||||
|
const initTime = toTimeStamp(formatDuring(this.$store.state.training.initTime));
|
||||||
|
startValue = initTime - this.PlanConvert.TranslationTime;
|
||||||
|
this.option.dataZoom[0].startValue = this.option.dataZoom[1].startValue = startValue - offsetTime;
|
||||||
|
this.option.dataZoom[0].endValue = this.option.dataZoom[1].endValue = startValue + offsetTime;
|
||||||
|
this.option.series = series;
|
||||||
|
this.myChart = echarts.init(document.getElementById(this.runPlanId));
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.setOption(this.option);
|
||||||
|
this.reSize({ width: document.documentElement.clientWidth - 10, height: document.documentElement.clientHeight - 55 });
|
||||||
|
this.myChart.on('click', this.mouseClick);
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateRunPlanData(data) {
|
||||||
|
const stations = this.$store.state.runPlan.stations;
|
||||||
|
const planData = this.$store.state.runPlan.planData;
|
||||||
|
const initialPlanData = this.$store.state.runPlan.initialPlanData;
|
||||||
|
if (data[0] && initialPlanData[data[0].serviceNumber]) {
|
||||||
|
Object.keys(initialPlanData[data[0].serviceNumber].trainMap).forEach(item => {
|
||||||
|
if (initialPlanData[data[0].serviceNumber].trainMap[item + ''].tripNumber == data[0].tripNumber) {
|
||||||
|
data[0].directionCode = initialPlanData[data[0].serviceNumber].trainMap[item + ''].directionCode;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (data[0]) {
|
||||||
|
data[0].secondTime = data[0].second;
|
||||||
|
}
|
||||||
|
this.series = this.PlanConvert.updateDataToModels(data, stations, this.kmRangeCoordMap,
|
||||||
|
planData, this.series, { color: '#FF00DE', width: 2 }
|
||||||
|
);
|
||||||
|
this.myChart && this.myChart.setOption({ series: this.series });
|
||||||
|
},
|
||||||
|
pushModels(series, models) {
|
||||||
|
if (models && models.length) {
|
||||||
|
models.forEach(elem => {
|
||||||
|
if (elem) {
|
||||||
|
series.push(elem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
},
|
||||||
|
popModels(series, models) {
|
||||||
|
if (models && models.length) {
|
||||||
|
models.forEach(elem => {
|
||||||
|
const index = series.indexOf(elem);
|
||||||
|
if (index >= 0) {
|
||||||
|
series.split(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return series;
|
||||||
|
},
|
||||||
|
xAxisPointFormat(params) {
|
||||||
|
return timeFormat(params.value);
|
||||||
|
},
|
||||||
|
yAxisPointFormat(params) {
|
||||||
|
return this.PlanConvert.computedFormatYAxis(this.stations, params);
|
||||||
|
},
|
||||||
|
xAxisLableFormat(value, index) {
|
||||||
|
if (value % 60 === 0) {
|
||||||
|
return timeFormat(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxisLableFormat(value, index) {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
xAxisInit() {
|
||||||
|
const list = [];
|
||||||
|
for (var time = this.PlanConvert.TranslationTime; time < 3600 * 24 + this.PlanConvert.TranslationTime; time++) {
|
||||||
|
list.push(time);
|
||||||
|
}
|
||||||
|
this.option.xAxis[0].data = list;
|
||||||
|
},
|
||||||
|
yAxisInit() {
|
||||||
|
if (Object.keys(this.PlanConvert).length) {
|
||||||
|
this.option.yAxis.min = this.PlanConvert.computedYaxisMinValue(this.stations);
|
||||||
|
this.option.yAxis.max = this.PlanConvert.computedYaxisMaxValue(this.stations);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTooltip(param) {
|
||||||
|
const station = this.stations[Math.floor((param.data[1] - this.PlanConvert.EdgeHeight) / this.PlanConvert.CoordMultiple)] || { name: '', kmRange: '' };
|
||||||
|
return [
|
||||||
|
`Point Data <hr size=1 style="margin: 3px 0">`,
|
||||||
|
`${this.$t('display.runPlan.stationName')}: ${station.name}<br>`,
|
||||||
|
`${this.$t('display.runPlan.stationMark')}: ${station.kmRange} km <br>`,
|
||||||
|
`${this.$t('display.runPlan.arrivalTime')}: ${timeFormat(param.data[0] + this.PlanConvert.TranslationTime)} (${param.data[0]})<br>`
|
||||||
|
].join('');
|
||||||
|
},
|
||||||
|
settingExac(data) {
|
||||||
|
this.absoluteTime = Math.abs(parseInt(data.endValue) - parseInt(data.startValue)) / 1000;
|
||||||
|
this.myChart && this.myChart.setOption({
|
||||||
|
xAxis: this.option.xAxis,
|
||||||
|
yAxis: this.option.yAxis
|
||||||
|
});
|
||||||
|
|
||||||
|
this.myChart && this.myChart.dispatchAction({
|
||||||
|
type: 'dataZoom',
|
||||||
|
dataZoomIndex: [0, 1],
|
||||||
|
startValue: parseInt(data.startValue / 1000),
|
||||||
|
endValue: parseInt(data.endValue / 1000)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
run(start) {
|
||||||
|
this.myChart && this.myChart.dispatchAction({
|
||||||
|
type: 'dataZoom',
|
||||||
|
dataZoomIndex: [0, 1],
|
||||||
|
startValue: parseInt(start - this.absoluteTime / 2),
|
||||||
|
endValue: parseInt(start + this.absoluteTime / 2)
|
||||||
|
});
|
||||||
|
this.loadInitData(this.series);
|
||||||
|
},
|
||||||
|
reSize(opt) {
|
||||||
|
if (this.myChart) {
|
||||||
|
this.myChart.resize({ width: opt.width, height: opt.height, silent: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped rel="stylesheet/scss" lang="scss">
|
||||||
|
/deep/ {
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 0px !important;
|
||||||
|
background-color: floralwhite !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -157,19 +157,19 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scope>
|
<style lang="scss" scope>
|
||||||
|
.content-route /deep/ .el-dialog__body {
|
||||||
|
width: 100%;
|
||||||
|
height:100%;
|
||||||
|
flex:1;
|
||||||
|
padding: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
.content-route{
|
.content-route{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
/deep/ {
|
|
||||||
.el-dialog__body{
|
|
||||||
width: 100%;
|
|
||||||
height:100%;
|
|
||||||
flex:1;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-box{
|
.content-box{
|
||||||
display:flex;
|
display:flex;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
@ -15,17 +15,17 @@
|
|||||||
border
|
border
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" :label="this.$t('planMonitor.runGraphName')" />
|
<el-table-column prop="name" :label="this.$t('planMonitor.runGraphName')" />
|
||||||
<el-table-column v-if="!(/^\/design\/userlist/.test(this.$route.fullPath))" :label="this.$t('global.status')">
|
<!-- <el-table-column v-if="!(/^\/design\/userlist/.test(this.$route.fullPath))" :label="this.$t('global.status')">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag>{{ handlerStatus(scope.row) }}</el-tag>
|
<el-tag>{{ handlerStatus(scope.row) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column> -->
|
||||||
<el-table-column
|
<!-- <el-table-column
|
||||||
v-if="!(/^\/design\/userlist/.test(this.$route.fullPath))"
|
v-if="!(/^\/design\/userlist/.test(this.$route.fullPath))"
|
||||||
prop="explanation"
|
prop="explanation"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
:label="this.$t('planMonitor.explanation')"
|
:label="this.$t('planMonitor.explanation')"
|
||||||
/>
|
/> -->
|
||||||
<el-table-column :label="this.$t('planMonitor.creationDate')">
|
<el-table-column :label="this.$t('planMonitor.creationDate')">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag type="success">{{ handleTime(scope.row.createTime) }}</el-tag>
|
<el-tag type="success">{{ handleTime(scope.row.createTime) }}</el-tag>
|
||||||
@ -33,7 +33,8 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="this.$t('global.operate')" width="400">
|
<el-table-column :label="this.$t('global.operate')" width="400">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button v-if="scope.row.status !=='1'" size="mini" class="button_box" type="success" :loading="scope.row.runplanLoading" @click="handleConfirm(scope.row)">{{ $t('planMonitor.load') }}</el-button>
|
<!-- {{ $t('planMonitor.load') }} -->
|
||||||
|
<el-button v-if="scope.row.status !=='1'" size="mini" class="button_box" type="success" :loading="scope.row.runplanLoading" @click="handleConfirm(scope.row)">编制</el-button>
|
||||||
<el-button v-if="isCreate && scope.row.status !=='1'" size="mini" class="button_box" type="primary" @click="handleEdit(scope.row)">{{ $t('planMonitor.modifyName') }}</el-button>
|
<el-button v-if="isCreate && scope.row.status !=='1'" size="mini" class="button_box" type="primary" @click="handleEdit(scope.row)">{{ $t('planMonitor.modifyName') }}</el-button>
|
||||||
<el-button v-if="isCreate && scope.row.status !=='1'" size="mini" class="button_box" type="danger" @click="handleDelete(scope.row)">{{ $t('global.delete') }}</el-button>
|
<el-button v-if="isCreate && scope.row.status !=='1'" size="mini" class="button_box" type="danger" @click="handleDelete(scope.row)">{{ $t('global.delete') }}</el-button>
|
||||||
<el-button v-if="isCreate && scope.row.status ==='0' && hasRelease" size="mini" class="button_box" type="primary" @click="handlePublish(scope.row)">{{ hasRelease?$t('global.release'):$t('planMonitor.applyRelease') }}</el-button>
|
<el-button v-if="isCreate && scope.row.status ==='0' && hasRelease" size="mini" class="button_box" type="primary" @click="handlePublish(scope.row)">{{ hasRelease?$t('global.release'):$t('planMonitor.applyRelease') }}</el-button>
|
||||||
|
@ -40,7 +40,8 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="导入运行图" name="three">
|
<!-- v-if="hasRelease" -->
|
||||||
|
<!-- <el-tab-pane label="导入运行图" name="three">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-button type="text" class="uploadDemo">
|
<el-button type="text" class="uploadDemo">
|
||||||
<input
|
<input
|
||||||
@ -53,7 +54,7 @@
|
|||||||
<i class="el-icon-plus" />
|
<i class="el-icon-plus" />
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-tab-pane>
|
</el-tab-pane> -->
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
@ -117,6 +118,10 @@ export default {
|
|||||||
{ required: true, message: this.$t('rules.enterTheNameOfTheRunGraph'), trigger: 'blur' }
|
{ required: true, message: this.$t('rules.enterTheNameOfTheRunGraph'), trigger: 'blur' }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
hasRelease() {
|
||||||
|
return this.$store.state.user.roles.includes('04') ||
|
||||||
|
this.$store.state.user.roles.includes('05');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
458
src/views/test/index.vue
Normal file
458
src/views/test/index.vue
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div :id="iscsId" v-loading="loading" :style="{ width: width +'px', height: height +'px',background:'#425a74' }" class="iscs-canvas" />
|
||||||
|
<el-button-group>
|
||||||
|
<el-button @click="doRemove"> 删除 </el-button>
|
||||||
|
<el-button @click="doBinding">绑定</el-button>
|
||||||
|
<el-button @click="doUnbinding">解绑</el-button>
|
||||||
|
<el-button @click="doSource"> 源数据 </el-button>
|
||||||
|
</el-button-group>
|
||||||
|
<el-input type="textarea" :rows="6" v-model="json" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Iscs from '@/iscs_new/map';
|
||||||
|
import orders from '@/iscs_new/utils/orders';
|
||||||
|
import shapeType from '@/iscs_new/constant/shapeType';
|
||||||
|
import ShapeBuilder from '@/iscs_new/plugins/shapeBuilder';
|
||||||
|
import ShapeProperty from '@/iscs_new/plugins/shapeProperty';
|
||||||
|
import ShapeContextMenu from '@/iscs_new/plugins/shapeContextMenu';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import { exitFullscreen } from '@/utils/screen';
|
||||||
|
import * as utils from '@/iscs_new/utils/utils';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
json: "{}",
|
||||||
|
dataZoom: {
|
||||||
|
offsetX: '0',
|
||||||
|
offsetY: '0',
|
||||||
|
scaleRate: '1'
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
scaleRate: '1',
|
||||||
|
origin: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selected: null, // 选择复制元素
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('iscs', [
|
||||||
|
'iscs'
|
||||||
|
]),
|
||||||
|
iscsId() {
|
||||||
|
return ['iscs', (Math.random().toFixed(5)) * 100000].join('_');
|
||||||
|
},
|
||||||
|
width() {
|
||||||
|
return document.documentElement.clientWidth;
|
||||||
|
},
|
||||||
|
height() {
|
||||||
|
return document.documentElement.clientHeight - 200;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.config.canvasSizeCount': function (val) {
|
||||||
|
this.resize();
|
||||||
|
},
|
||||||
|
'$store.state.socket.equipmentStatus': function (val) {
|
||||||
|
if (val.length) {
|
||||||
|
this.stateMessage(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
document.getElementById(this.iscsId).oncontextmenu = function (e) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$iscs = new Iscs({
|
||||||
|
dom: document.getElementById(this.iscsId),
|
||||||
|
draw: true,
|
||||||
|
config: {
|
||||||
|
renderer: 'canvas',
|
||||||
|
width: this.width,
|
||||||
|
height: this.height
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
scaleRate: 1,
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 0
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
ShapeBuilder,
|
||||||
|
ShapeProperty,
|
||||||
|
ShapeContextMenu
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
Vue.prototype.$iscs = this.$iscs;
|
||||||
|
this.$iscs.on('viewLoaded', this.onUpdate, this);
|
||||||
|
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||||
|
this.$iscs.on('click', this.onClick, this);
|
||||||
|
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||||
|
|
||||||
|
const opts = { panEnable: true, zoomEnable: true, keyEnable: true, draggle: true, selecting: true, selectable: true, reflect: true }
|
||||||
|
this.$iscs.setMap([
|
||||||
|
{
|
||||||
|
type: 'Device',
|
||||||
|
name: 'test',
|
||||||
|
isActive: false,
|
||||||
|
isFocus: false,
|
||||||
|
shapeList: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
type: 'Rect',
|
||||||
|
shape: {},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
stateList: [
|
||||||
|
{ status: 'st1', hide: false, shape: {}, style:{ fill: 'yellow', stroke: 'black'} },
|
||||||
|
{ status: 'st2', hide: false, shape: {}, style:{ fill: 'blue', stroke: 'black'} }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
type: 'Circle',
|
||||||
|
shape: {},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
stateList: [
|
||||||
|
{ status: 'st1', hide: false, shape: {}, style:{ fill: 'yellow', stroke: 'black'} },
|
||||||
|
{ status: 'st2', hide: false, shape: {}, style:{ fill: 'blue', stroke: 'black'} }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
stateList: [
|
||||||
|
{ status: 's1', frameList: [[{name: 'a', status: 'st1'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st2'}]], weight: 2, loop: true, delay: 2000, time: 200, needDefault: true },
|
||||||
|
{ status: 's2', frameList: [[{name: 'a', status: 'st2'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st1'}, {name: 'b', status: 'st2'}]], weight: 1, loop: true, delay: 5000, time: 500, needDefault: false }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
], {
|
||||||
|
elementList: [
|
||||||
|
{
|
||||||
|
code: '1',
|
||||||
|
name: 'a',
|
||||||
|
type: 'Rect',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
width: 30,
|
||||||
|
height: 30
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: '100'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '2',
|
||||||
|
name: 'b',
|
||||||
|
type: 'Circle',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
cx: 100,
|
||||||
|
cy: 100,
|
||||||
|
r: 10,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: '100'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '3',
|
||||||
|
name: 'a',
|
||||||
|
type: 'Rect',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: Math.PI/4,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
x: 200,
|
||||||
|
y: 100,
|
||||||
|
width: 30,
|
||||||
|
height: 30
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: '101'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '4',
|
||||||
|
name: 'b',
|
||||||
|
type: 'Circle',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
scale: [0.5, 0.5],
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
cx: 200,
|
||||||
|
cy: 100,
|
||||||
|
r: 10,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: '101'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '5',
|
||||||
|
name: 'c',
|
||||||
|
type: 'Droplet',
|
||||||
|
base: {
|
||||||
|
scale: [0.5, 0.5],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
cx: 300,
|
||||||
|
cy: 200,
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '6',
|
||||||
|
name: 'd',
|
||||||
|
type: 'Droplet',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: Math.PI/2,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
cx: 400,
|
||||||
|
cy: 200,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '7',
|
||||||
|
name: 'a',
|
||||||
|
type: 'Rect',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [100, 0],
|
||||||
|
rotation: Math.PI/2,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
shape: {
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
width: 30,
|
||||||
|
height: 60
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
fill: 'red',
|
||||||
|
stroke: 'black'
|
||||||
|
},
|
||||||
|
composeCode: ''
|
||||||
|
},
|
||||||
|
],
|
||||||
|
composeList: [
|
||||||
|
{
|
||||||
|
code: '100',
|
||||||
|
type: 'Device',
|
||||||
|
elementCodes: ['1', '2'],
|
||||||
|
base: {
|
||||||
|
scale: [0.5, 0.5],
|
||||||
|
position: [100, 100],
|
||||||
|
rotation: Math.PI/2,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
composeCode: '1000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '101',
|
||||||
|
type: 'Device',
|
||||||
|
elementCodes: ['3', '4'],
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [200, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
composeCode: '1000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: '1000',
|
||||||
|
type: 'Device',
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false
|
||||||
|
},
|
||||||
|
elementCodes: ['100', '101'],
|
||||||
|
composeCode: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, opts);
|
||||||
|
|
||||||
|
window.document.oncontextmenu = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onUpdate(e) {
|
||||||
|
this.$iscs.update([
|
||||||
|
{ status: 's1', code: '100', type: 'Device' },
|
||||||
|
{ status: 's2', code: '101', type: 'Device' }
|
||||||
|
]);
|
||||||
|
setTimeout(e => {
|
||||||
|
// this.$iscs.update([
|
||||||
|
// { status: 's0', code: '100', type: 'Device' },
|
||||||
|
// { status: 's0', code: '101', type: 'Device' },
|
||||||
|
// ])
|
||||||
|
}, 15000)
|
||||||
|
},
|
||||||
|
// 键盘快捷键事件
|
||||||
|
onKeyboard(hook) {
|
||||||
|
console.log(hook);
|
||||||
|
},
|
||||||
|
// 点击选择事件
|
||||||
|
onClick(em) {
|
||||||
|
this.selected = em;
|
||||||
|
},
|
||||||
|
// 右键点击事件
|
||||||
|
onContextMenu(em) {
|
||||||
|
this.selected = em;
|
||||||
|
},
|
||||||
|
doRemove() {
|
||||||
|
if (this.selected) {
|
||||||
|
this.$iscs.render([
|
||||||
|
{
|
||||||
|
model: this.selected.model,
|
||||||
|
action: { order: orders.Delete, shapeType: shapeType.Compose }
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doBinding() {
|
||||||
|
const controller = this.$iscs.getController();
|
||||||
|
const storage = controller.getStorage()
|
||||||
|
const values = storage.values();
|
||||||
|
if (values.length > 1) {
|
||||||
|
const elem = {
|
||||||
|
model: {
|
||||||
|
code: utils.getUID('compose'),
|
||||||
|
type: 'Device',
|
||||||
|
elementCodes: values.map(el => el.model.code),
|
||||||
|
base: {
|
||||||
|
scale: [1, 1],
|
||||||
|
position: [0, 0],
|
||||||
|
rotation: 0,
|
||||||
|
hide: false,
|
||||||
|
},
|
||||||
|
composeCode: '',
|
||||||
|
},
|
||||||
|
action: { order: orders.Binding, shapeType: shapeType.Compose }
|
||||||
|
}
|
||||||
|
this.$iscs.render([elem]);
|
||||||
|
} else {
|
||||||
|
this.$message.info('请选择两个及其以上数目元素');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doUnbinding() {
|
||||||
|
if (this.selected) {
|
||||||
|
this.$iscs.render([
|
||||||
|
{
|
||||||
|
model: this.selected.model,
|
||||||
|
action: { order: orders.Unbinding, shapeType: shapeType.Compose }
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
doSource() {
|
||||||
|
console.log(this.$iscs.getSource());
|
||||||
|
this.json = JSON.stringify(this.$iscs.getSource())
|
||||||
|
},
|
||||||
|
resize() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$iscs && this.$iscs.resize({ width: this.width, height: this.height });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
back() {
|
||||||
|
this.group = this.$route.query.group;
|
||||||
|
this.$store.dispatch('training/over').then(() => {
|
||||||
|
putJointTrainingSimulationUserNew(this.group).then(() => {
|
||||||
|
this.$router.replace({ path: `/trainroom`, query: { group: this.group, lineCode:this.$route.query.lineCode } });
|
||||||
|
exitFullscreen();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy() {
|
||||||
|
if (this.$iscs) {
|
||||||
|
this.$iscs.destroy();
|
||||||
|
this.$iscs = null;
|
||||||
|
Vue.prototype.$iscs = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stateMessage(val) {
|
||||||
|
this.$iscs && this.$iscs.setDeviceStatus(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||||
|
.iscs-button{
|
||||||
|
position: absolute;
|
||||||
|
float: right;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 15px;
|
||||||
|
}
|
||||||
|
.iscs-canvas{
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user