rt-sim-training-client/src/views/newMap/newMapdraft/index.vue

716 lines
27 KiB
Vue
Raw Normal View History

2019-11-29 12:51:58 +08:00
<template>
<transition name="el-zoom-in-center">
<div class="mapPaint">
2019-12-10 16:57:31 +08:00
<div v-show="maskOpen" class="mask" />
2019-11-29 12:51:58 +08:00
<div class="map-view">
<div class="operation_box">
<el-button-group>
<el-button size="small" :disabled="!stepData.length" @click="revocation">撤销</el-button>
<el-button size="small" :disabled="!recoverStepData.length" @click="recover">恢复</el-button>
</el-button-group>
</div>
<div class="operation_box back_box">
<el-button size="small" @click="backRoute">返回</el-button>
2020-04-30 17:22:10 +08:00
<el-button size="small" @click="updateObjAxis">更新坐标</el-button>
</div>
2019-11-29 12:51:58 +08:00
<jlmap-visual ref="jlmapVisual" @onSelect="clickEvent" @onMenu="onContextmenu" />
</div>
<div class="map-draft">
<div v-show="viewDraft === 'draft'" class="box">
<map-operate
ref="mapOperate"
:map-info="mapInfo"
:selected="selected"
:map-saveing="mapSaveing"
@handleSelectPhysicalView="handleSelectPhysicalView"
@saveMapEvent="saveMapEvent"
@verifyMapEvent="verifyMapEvent"
@generateCIEvent="generateCIEvent"
2019-11-29 12:51:58 +08:00
@updateMapModel="updateMapModel"
@setCenter="setCenter"
@selectView="selectViewDraft"
@showMap="showMap"
/>
</div>
<div v-show="viewDraft != 'draft'" class="box">
<data-relation
ref="dataRelation"
:map-info="mapInfo"
:selected="selected"
@selectView="selectViewDraft"
@showMap="showMap"
/>
</div>
<config-map
ref="configMap"
@handleSelectPhysicalView="handleSelectPhysicalView"
/>
2020-05-11 14:45:07 +08:00
<ci-config ref="ciConfig" />
2019-11-29 12:51:58 +08:00
</div>
2020-05-15 15:58:08 +08:00
<pop-menu ref="popMenu" :menu="menu" />
2019-11-29 12:51:58 +08:00
</div>
</transition>
</template>
<script>
2020-05-11 17:36:21 +08:00
import { saveMap, getMapDetail, verifyMap, postBuildMapImport, getRouteNewList, getAutoReentryList } from '@/api/jmap/mapdraft';
2020-05-15 15:58:08 +08:00
import { ViewMode, TrainingMode, getDeviceMenuByDeviceType, DeviceMenu } from '@/scripts/ConstDic';
2019-11-29 12:51:58 +08:00
import { checkLoginLine } from '@/api/login';
import JlmapVisual from '@/views/newMap/jlmapNew/index';
import MapOperate from './mapoperate/index';
import { EventBus } from '@/scripts/event-bus';
import { mapGetters } from 'vuex';
2020-05-11 14:45:07 +08:00
import CiConfig from './ciConfig';
2020-05-15 15:58:08 +08:00
import PopMenu from '@/components/PopMenu';
2019-11-29 12:51:58 +08:00
import ConfigMap from './configMap';
import DataRelation from './dataRelation/index';
export default {
name: 'MapView',
components: {
JlmapVisual,
MapOperate,
DataRelation,
2020-05-11 14:45:07 +08:00
ConfigMap,
2020-05-15 15:58:08 +08:00
CiConfig,
PopMenu
2019-11-29 12:51:58 +08:00
},
data() {
return {
viewSelect: ViewMode.MIX,
mapSaveing: false,
ViewMode: ViewMode,
viewDraft: 'draft',
autoSaveTask: null,
selected: null,
mapInfo: { name: this.$t('map.pleaseSelectMap') },
2019-12-27 15:23:42 +08:00
timeDemon: null,
oldDevice: null,
size: {
width: document.documentElement.clientWidth - 521,
height: document.documentElement.clientHeight - 90
2020-04-30 17:22:10 +08:00
},
updtModel: {
code: '',
scaling: '',
origin: {
x: '',
y: ''
}
2020-05-15 15:58:08 +08:00
},
menu: [],
menuNormal: []
2019-11-29 12:51:58 +08:00
};
},
computed: {
...mapGetters('map', [
'stepData',
2020-05-15 15:58:08 +08:00
'recoverStepData',
'stationList'
2019-12-10 16:57:31 +08:00
]),
maskOpen() {
return this.$store.state.config.maskOpen;
}
2019-11-29 12:51:58 +08:00
},
watch: {
'$store.state.map.mapDataLoadedCount': function (val) {
this.initAutoSaveTask();
},
'$store.state.app.windowSizeCount': function() {
this.setWindowSize();
},
2019-11-29 12:51:58 +08:00
$route() {
this.clearAutoSave();
2019-11-29 12:51:58 +08:00
this.$nextTick(() => {
this.loadInitPage();
});
2020-05-15 15:58:08 +08:00
},
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](DeviceMenu.Cancel)) {
this.popDoShow(this.$store.state.menuOperation.menuPosition);
} else {
this.popDoClose();
}
2019-11-29 12:51:58 +08:00
}
},
mounted() {
this.setWindowSize();
2019-11-29 12:51:58 +08:00
this.loadInitPage();
this.timeDemon = setInterval(() => {
checkLoginLine();
}, 5000 * 60);
EventBus.$on('SELECTON', () => {
this.selected = null;
});
2019-11-29 12:51:58 +08:00
},
beforeDestroy() {
EventBus.$off('SELECTON');
2019-11-29 12:51:58 +08:00
this.clearAutoSave();
this.$store.dispatch('map/mapClear');
if (this.timeDemon) {
clearTimeout(this.timeDemon);
}
},
methods: {
2020-04-30 17:22:10 +08:00
getMapOrigin() {
const dataZoom = this.$store.state.map.dataZoom;
if (dataZoom && dataZoom.offsetX) {
this.updtModel.origin.x = Number.parseInt(dataZoom.offsetX);
this.updtModel.origin.y = Number.parseInt(dataZoom.offsetY);
this.updtModel.scaling = dataZoom.scaleRate;
}
},
2020-05-15 15:58:08 +08:00
// 设置地图定位
mapLocation(item) {
if (item) {
this.$store.dispatch('training/updateOffsetStationCode', { offsetStationCode: item.code });
this.popDoClose();
}
},
initMenu() {
this.menuNormal = [];
this.stationList.forEach(station => {
if (station.chargeStationCodeList && station.chargeStationCodeList.length) {
const node = {
label: station.name,
children: []
};
station.chargeStationCodeList.forEach(item => {
const next = this.$store.getters['map/getDeviceByCode'](item);
node.children.push({
code: next.code,
label: next.name,
handler: this.mapLocation
});
});
this.menuNormal.push(node);
}
});
this.menu = [...this.menuNormal];
},
popDoShow(point) {
this.popClickEvent();
this.initMenu();
if (this.$refs && this.$refs.popMenu && this.menu && this.menu.length) {
this.$refs.popMenu.resetShowPosition(point);
}
},
popClickEvent() {
const self = this;
window.onclick = function (e) {
self.popDoClose();
};
},
popDoClose() {
if (this.$refs && this.$refs.popMenu) {
this.$refs.popMenu.close();
}
},
2020-04-30 17:22:10 +08:00
updateObjAxis() {
this.getMapOrigin();
this.$confirm('您确认按当前绘图位置更新坐标及缩放比例?', this.$t('tip.hint'), {
confirmButtonText: this.$t('tip.confirm'),
cancelButtonText: this.$t('tip.cancel'),
type: 'warning'
}).then(() => {
const map = this.$store.state.map.map;
this.$store.dispatch('map/saveMapDeviceDefaultRelations').then(() => {
const param = {
mapId: this.$route.params.mapId,
skinVO: {
code: this.$store.state.map.map.skinVO.code,
2020-05-11 14:45:07 +08:00
name: this.$store.state.map.map.skinVO.name
},
origin: {
x: this.updtModel.origin.x || map.origin.x,
y: this.updtModel.origin.y || map.origin.y
},
scaling: this.updtModel.scaling
2020-04-30 17:22:10 +08:00
};
saveMap(Object.assign(map, param)).then(response => {
this.$message.success(this.$t('map.updateSuccessfully'));
}).catch(() => {
this.$messageBox(this.$t('map.updateFailed'));
});
});
}).catch(() => { });
},
setWindowSize() {
this.$nextTick(() => {
const width = this.$store.state.app.width - 521;
const height = this.$store.state.app.height - 90;
this.$store.dispatch('config/resize', { width, height });
});
},
2019-11-29 12:51:58 +08:00
endViewLoading(isSuccess) {
if (!isSuccess) {
this.$store.dispatch('map/mapClear');
}
this.$nextTick(() => {
EventBus.$emit('viewLoading', false);
});
},
2020-04-10 17:23:53 +08:00
showMap() { // 显示地图元素
2019-11-29 12:51:58 +08:00
this.$refs.configMap.doShow();
},
selectViewDraft(data) {
this.viewDraft = data;
2020-04-30 17:52:37 +08:00
if (data != 'draft') {
this.$refs.dataRelation.initLoad();
}
2019-11-29 12:51:58 +08:00
},
loadInitPage() {
this.$store.dispatch('training/changeMode', { mode: TrainingMode.MAP_EDIT });
this.mapInfo = { name: this.$t('map.pleaseSelectMap'), id: this.$route.params.mapId };
if (parseInt(this.mapInfo.id)) {
this.mapInfo.name = this.$route.query.name;
getMapDetail(this.$route.params.mapId).then(response => {
this.$store.dispatch('map/setMapData', response.data).then(resp => {
this.$store.dispatch('training/setMapDefaultState');
});
this.setDelayUnlockStatus(response.data, '00');
this.initAutoSaveTask();
}).catch((error) => {
console.log(error, '加载地图错误提示');
2019-11-29 12:51:58 +08:00
this.$message.error(this.$t('tip.failedLoadMap'));
this.endViewLoading();
});
} else {
this.endViewLoading();
}
},
initAutoSaveTask() {
const timeout = 1000 * 60 * 3;
this.clearAutoSave(this.autoSaveTask);
if (this.viewDraft == 'draft') {
this.autoSaveTask = setInterval(this.saveMapEvent, timeout);
}
},
clearAutoSave() {
if (this.autoSaveTask) {
clearInterval(this.autoSaveTask);
this.autoSaveTask = null;
}
},
generateCIEvent() {
2020-05-11 14:45:07 +08:00
this.$refs.ciConfig.show();
},
handleSelectControlPage (model) {
2019-11-29 12:51:58 +08:00
if (this.$refs.mapOperate) {
this.$refs.mapOperate.handleSelectControlPage(model);
2019-11-29 12:51:58 +08:00
this.$store.dispatch('menuOperation/setMapDrawSelectCount');
}
},
handleSelectPhysicalView(handle) {
if (this.$refs.jlmapVisual) {
this.$refs.jlmapVisual.setLevelVisible(handle);
}
},
clickEvent(em) {
2020-03-31 14:41:17 +08:00
const device = this.getDeviceByEm(em);
2019-12-27 15:23:42 +08:00
this.deviceHighLight(this.oldDevice, false);
this.deviceHighLight(device, true);
this.oldDevice = device;
2019-11-29 12:51:58 +08:00
this.onSelect(device);
if (this.$refs.dataRelation && this.viewDraft != 'draft') {
this.$refs.dataRelation.setSelected(device);
}
},
// 获取设备数据
getDeviceByEm(em) {
var device = this.$store.getters['map/getDeviceByCode'](em.deviceCode) || null;
if (device) {
device._viewVal = em.val;
}
return device;
},
onSelect(device) {
2020-07-23 17:09:29 +08:00
this.selected = device || null;
this.selected && this.handleSelectControlPage(device);
2019-11-29 12:51:58 +08:00
},
onContextmenu(em) {
this.point = {
x: em.clientX,
y: em.clientY
};
if (!em.deviceType) {
var menu = getDeviceMenuByDeviceType('Cancel');
this.$store.dispatch('menuOperation/setPopMenu', { position: this.point, menu: menu });
}
},
verifySectionPoint(map) { // 校验区段坐标不为空
let flag = true;
map.sectionList.forEach(elem => {
if (elem.points.length > 0) {
for (let index = 0; index < elem.points.length; index++) {
if (String(elem.points[index].x) == 'undefined' || String(elem.points[index].y) == 'undefined') {
this.$message(`${elem.name}${this.$t('tip.sectionPointsDeficiency')}`);
flag = false;
}
}
} else {
this.$message(this.$t('tip.sectionPointsDeficiency'));
flag = false;
}
});
return flag;
},
verifySectionRelation(map) {
let flag = true;
const tipInfoList = [];
map.sectionList.forEach(section => {
section.type === '01' && map.sectionList.forEach(item => {
if (section.code !== item.code && item.type === '01' && this.checkSectionPointsHasCoincide(section.points, item.points) && !this.checkCorrelation(section, item)) {
2020-04-15 09:37:42 +08:00
tipInfoList.push('区段' + section.name + '(' + section.code + '): 或者区段' + item.name + '(' + item.code + ')' + '关联关系设置错误!' );
}
});
});
if (!tipInfoList.length) {
flag = true;
} else {
flag = false;
this.$messageBox(this.$t('tip.dataValidationFailed'));
this.tableToExcel(tipInfoList);
}
return flag;
},
async verifyInterlockDevice(map) {
let flag = true;
const tipInfoList = [];
const routeCodeList = [];
const cycleCodeList = [];
const resp1 = await getRouteNewList(this.$route.params.mapId, {pageSize:9999, pageNum:1});
if (resp1.data && resp1.data.list) {
resp1.data.list.forEach(item => {
routeCodeList.push(item.code);
});
}
const resp2 = await getAutoReentryList(this.$route.params.mapId, {pageSize:9999, pageNum:1});
if (resp2.data && resp2.data.list) {
resp2.data.list.forEach(item => {
cycleCodeList.push(item.code);
});
}
map.cycleButtonList.forEach(cycleButton => {
if (!cycleCodeList.includes(cycleButton.cycleCode)) {
flag = false;
tipInfoList.push('自动折返功能按钮' + cycleButton.name + '(' + cycleButton.code + ')' + '的关联自动折返数据不存在!');
}
});
map.automaticRouteButtonList.forEach(routeButton => {
if (!routeCodeList.includes(routeButton.automaticRouteCode)) {
flag = false;
tipInfoList.push('自动进路功能按钮' + routeButton.name + '(' + routeButton.code + ')' + '的关联进路数据不存在!');
}
});
if (!flag) {
this.$messageBox(this.$t('tip.dataValidationFailed'));
this.tableToExcel(tipInfoList);
}
return flag;
},
verifyStationPosition(map) {
let flag = true;
const tipInfoList = [];
map.stationStandList.forEach(stationStand => {
const section = this.$store.getters['map/getDeviceByCode'](stationStand.standTrackCode);
const list = [];
section.points.forEach(point => {
list.push(point.x);
});
if (stationStand.position.x > Math.max(...list) || stationStand.position.x < Math.min(...list)) {
flag = false;
tipInfoList.push('站台' + stationStand.name + '(' + stationStand.code + ')' + '位置偏移出关联站台轨,请检查关联站台轨是否正确!');
}
});
if (!flag) {
this.$messageBox(this.$t('tip.dataValidationFailed'));
this.tableToExcel(tipInfoList);
}
return flag;
},
verifySignalPosition(map) {
let flag = true;
const tipInfoList = [];
map.signalList.forEach(signal => {
const section = this.$store.getters['map/getDeviceByCode'](signal.sectionCode);
if (section) {
const offsetX = signal.positionPoint ? signal.positionPoint.x : 0;
const signalPositionX = signal.position.x - offsetX;
const max = Math.max(section.points[section.points.length - 1].x, section.points[0].x);
const min = Math.min(section.points[section.points.length - 1].x, section.points[0].x);
if (signalPositionX < min && signalPositionX > max) {
tipInfoList.push('信号机' + signal.name + '(' + signal.code + ')未在其关联的区段' + section.name + '(' + section.code + ')里');
}
} else {
tipInfoList.push('信号机' + signal.name + '(' + signal.code + ')所关联的区段不存在');
}
});
if (!tipInfoList.length) {
flag = true;
} else {
flag = false;
this.$messageBox(this.$t('tip.dataValidationFailed'));
this.tableToExcel(tipInfoList);
}
return flag;
},
checkPointsCoincide(point1, point2) { // 校验两点是否重合
if (point1 && point2) {
return point1.x === point2.x && point1.y === point2.y;
}
return false;
},
checkSectionPointsHasCoincide(points1, points2) { // 校验两区段的左右点是否有重合
return points1.length && points2.length && (this.checkPointsCoincide(points1[0], points2[0]) || this.checkPointsCoincide(points1[0], points2[points2.length - 1]) || this.checkPointsCoincide(points1[points1.length - 1], points2[points2.length - 1]) || this.checkPointsCoincide(points1[points1.length - 1], points2[0]));
},
checkCorrelation(section1, section2) { // 校验后者是否与前者有关联关系
return section1.leftSectionCode === section2.code || section1.rightSectionCode === section2.code;
},
2019-11-29 12:51:58 +08:00
saveMapEvent() { // 保存地图
const map = this.$store.state.map.map;
2020-06-22 13:49:42 +08:00
// map.sectionList.forEach(item => {
// item.belongStation = '';
2020-04-17 18:44:14 +08:00
// });
2019-11-29 12:51:58 +08:00
if (this.$refs.jlmapVisual && map && parseInt(this.$route.params.mapId)) {
if (this.verifySectionPoint(map)) {
this.mapSaveing = true;
this.$store.dispatch('map/saveMapDeviceDefaultRelations').then(() => { // 草稿地图关系处理
2019-12-02 14:50:48 +08:00
saveMap(Object.assign(map, { mapId: this.$route.params.mapId })).then(response => {
2019-11-29 12:51:58 +08:00
this.$message.success(this.$t('tip.saveSuccessfully'));
this.mapSaveing = false;
this.initAutoSaveTask();
}).catch(error => {
console.log(error);
this.$messageBox(this.$t('tip.saveFailed'));
this.mapSaveing = false;
if (error.code === 40004 || error.code === 40005 || error.code === 40003) {
this.clearAutoSave();
} else {
this.initAutoSaveTask();
}
});
}).catch(error => {
console.log(error, '错误提示');
this.mapSaveing = false;
this.$message(this.$t('tip.saveFailed'));
});
}
}
},
2020-05-09 17:32:13 +08:00
async verifyMapEvent() {
2019-11-29 12:51:58 +08:00
if (this.$refs.jlmapVisual) {
const map = this.$store.state.map.map;
if (map && this.$route.params.mapId) {
2020-05-09 17:32:13 +08:00
const checkInterlockDevice = await this.verifyInterlockDevice(map);
if (this.verifySectionRelation(map) && this.verifySignalPosition(map) && checkInterlockDevice && this.verifyStationPosition(map)) {
verifyMap(this.$route.params.mapId).then(res => {
if (res.data.length) {
this.tableToExcel(res.data);
this.$messageBox(this.$t('tip.dataValidationFailed'));
} else {
this.$message.success(this.$t('tip.dataValidationSuccess'));
}
}).catch(() => {
this.$message.error(this.$t('tip.requestFailed'));
});
}
2019-11-29 12:51:58 +08:00
}
}
},
tableToExcel(data) {
const filterVal = ['index'];
const arr = [];
data.forEach(item => {
arr.push({ index: item });
});
const dataList = this.formatJson(filterVal, arr);
import('@/utils/Export2Excel').then(excel => {
excel.export_json_to_excel([this.$t('tip.dataQuestion')], dataList, this.$t('tip.dataList'));
});
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]));
},
setDelayUnlockStatus(data, status) {
if (data && data.delayShowList) {
data.delayShowList.forEach(elem => {
elem.status = status;
});
}
},
backRoute() {
this.$router.push({ path: `/design/usermap/home` });
},
2019-11-29 12:51:58 +08:00
updateMapModel(models) {
this.$store.dispatch('map/updateMapDevices', models);
},
// 撤销
revocation() {
this.$store.dispatch('map/setRevocation');
},
// 恢复
recover() {
this.$store.dispatch('map/setRecover');
},
// 设置显示中心
setCenter(code) {
this.$refs.jlmapVisual.setCenter(code);
2019-12-27 15:23:42 +08:00
const device = this.$store.getters['map/getDeviceByCode'](code);
this.deviceHighLight(this.oldDevice, false);
this.deviceHighLight(device, true);
this.oldDevice = device;
2019-11-29 12:51:58 +08:00
},
createMap() {
this.$refs.mapCreate.show();
},
importf() { // 导入地图jsons数据
const loading = this.$loading({
lock: true,
text: '正在导入中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
setTimeout(() => {
const obj = this.$refs.files;
if (!obj.files) return;
const f = obj.files[0];
const reader = new FileReader();
const that = this;
reader.readAsText(f, 'utf-8');
reader.onload = function(e) {
const data = e.target.result;
postBuildMapImport(JSON.parse(data)).then(res => {
loading.close();
that.$message.success('导入成功!');
that.refresh();
loading.close();
}).catch(error => {
loading.close();
that.$message.error('导入失败' + error.message);
});
obj.value = '';
};
});
2019-12-27 15:23:42 +08:00
},
// 高亮设备
deviceHighLight(device, flag) {
if (device && device.instance && typeof device.instance.drawSelected === 'function' ) {
if (device._type === 'Section' && device.type === '04') {
device.relevanceSectionList.forEach(item => {
const sectionModel = this.$store.getters['map/getDeviceByCode'](item);
sectionModel && sectionModel.instance.drawSelected(flag);
});
} else if (device._type === 'Section' && device.type === '01' && device.logicSectionCodeList && device.logicSectionCodeList.length) {
device.logicSectionCodeList.forEach(item => {
const sectionModel = this.$store.getters['map/getDeviceByCode'](item);
sectionModel && sectionModel.instance.drawSelected(flag);
});
} else {
device.instance.drawSelected(flag);
}
}
2019-11-29 12:51:58 +08:00
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
/deep/ {
.menu-item{
background: #f1ecec;
.pop-menu {
background: #5F9EA0;
}
}
}
2019-12-10 16:57:31 +08:00
.mask{
opacity: 0;
background: #000;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 9;
}
2019-11-29 12:51:58 +08:00
.operation_box{
position: absolute;
right: 20px;
2020-03-11 10:53:09 +08:00
top: 15px;
2019-11-29 12:51:58 +08:00
z-index: 9;
}
.back_box{
left: 150px;
2020-04-28 18:16:04 +08:00
display: inline-block;
2020-04-30 17:22:10 +08:00
width: 180px;
}
2019-11-29 12:51:58 +08:00
.map-draft{
/deep/{
.v-modal{
opacity: 0;
}
}
}
.box{
height: 100%;
}
.mapPaint{
height: 100%;
overflow: hidden;
2019-12-10 16:57:31 +08:00
position: relative;
2019-11-29 12:51:58 +08:00
}
.map-view {
float: left;
width: calc(100% - 520px);
2019-11-29 12:51:58 +08:00
position: relative;
}
.map-draft {
float: right;
width: 520px;
height: 100%;
// /deep/ .el-scrollbar__view {
// width: 510px !important;
// height: calc(100% - 40px);
// }
}
.physical-view {
line-height: 25px;
height: 60px;
padding-left: 12px;
.el-checkbox {
width: 70px;
margin: 0;
margin-right: 12px;
}
}
.uploadDemo {
position: relative;
overflow: hidden;
float: right;
padding: 3px 0;
margin-right: 3px;
cursor: pointer;
input {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
opacity: 0;
cursor: pointer;
}
}
</style>