rt-sim-training-client/src/views/ibp/ibpsystem/index.vue
2020-10-10 09:10:42 +08:00

320 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div :id="ibpId" v-loading="loading" :style="{ width: canvasWidth+'px', height: canvasHeight +'px',background:'#000' }" class="ibp-canvas" />
<el-button v-if="showBackButton" class="ibp-button" type="primary" @click="back">{{ $t('global.back') }}</el-button>
<audio id="buzzer" controls loop="loop">
<source :src="buzzerAudio" type="audio/mpeg">
</audio>
</div>
</template>
<script>
import Vue from 'vue';
import IbpPan from '@/ibp/ibpPan';
import { parser } from '@/ibp/utils/parser';
import { mapGetters } from 'vuex';
import { exitFullscreen } from '@/utils/screen';
import { handlerIbpEvent } from '@/api/simulation';
import { IbpOperation } from '@/scripts/ConstDic';
import { creatSubscribe, clearSubscribe, displayTopic} from '@/utils/stomp';
import { getToken } from '@/utils/auth';
import { getIbpInfoByStation } from '@/api/ibp';
import { getSimulationInfoNew, getIbpInitialState } from '@/api/simulation';
import BuzzerAudio from '@/assets/buzzer.mp3';
export default {
name: 'Ibp',
props: {
size: {
type: Object,
default() {
return null;
}
}
},
data() {
return {
width: this.$store.state.config.width,
height: this.$store.state.config.height,
offsetX: 0,
dataZoom: {
offsetX: '0',
offsetY: '0',
scaleRate: '1'
},
config: {
scaleRate: '1',
origin: {
x: 0,
y: 0
}
},
showBackButton: true,
initTime: '',
started: false,
loading: false,
stationCode: '',
banUpOpenScreenDoor: false,
banDownOpenScreenDoor: false,
buzzerAudio:BuzzerAudio
};
},
computed: {
...mapGetters([
'canvasWidth',
'canvasHeight'
]),
ibpId() {
return ['ibp', (Math.random().toFixed(5)) * 100000].join('_');
},
drawWay() {
return this.$route.query.drawWay + '';
}
},
watch: {
'$store.state.config.canvasSizeCount': function (val) {
this.reSize();
},
'$store.state.app.windowSizeCount': function() {
this.setWindowSize();
},
'$store.state.socket.simulationIbpStatus': function (val) {
if (val && val[this.stationCode]) {
this.statusMessage(val[this.stationCode]);
this.controlAudio(val[this.stationCode].jjtcBuzzer);
}
},
'$store.state.socket.simulationTimeSync': function (time) { // 仿真时间更新
if (this.$ibp) {
this.initClockTime(time);
}
}
},
async mounted() {
this.setWindowSize();
if (this.$route.query.noPreLogout) {
this.subscribe();
getSimulationInfoNew(this.$route.query.group).then(resp => {
if (resp.data && resp.data.systemTime) {
this.initTime = resp.data.systemTime;
}
});
}
this.initIbp();
if (this.$route.query.loadAll && this.$route.query.stationCode) {
await this.show(this.$route.query.stationCode);
await this.setMoveInit(true);
this.showBackButton = false;
}
},
beforeDestroy() {
if (this.$route.query.noPreLogout) {
this.clearSubscribe();
this.$ibp.setClockStart(false);
}
this.ibpDestroy();
},
methods: {
initIbp(offsetX = 0) {
this.ibpDestroy();
this.loading = true;
this.$ibp = new IbpPan({
dom: document.getElementById(this.ibpId),
config: {
renderer: 'canvas',
width: this.canvasWidth,
height: this.canvasHeight
},
options: {
scaleRate: this.$route.path.includes('design/ibp/edit') ? 1 : this.canvasWidth / 1920,
offsetX: offsetX,
offsetY: 0
},
methods: {
viewLoaded: this.handleViewLoaded
}
});
Vue.prototype.$ibp = this.$ibp;
this.initClockTime(this.initTime || this.$store.state.socket.simulationTimeSync);
this.$ibp.on('contextmenu', this.onContextMenu, this);
if (this.$route.query.group) {
this.$ibp.on('selected', this.onSelected, this);
this.$ibp.on('mouseDown', this.onMouseDown, this);
}
},
async show (deviceCode, ibpPart) {
if (!deviceCode) {
return;
}
try {
// const ibpDatas = ibpData[deviceCode];
const res = await getIbpInfoByStation(this.$route.query.mapId, deviceCode);
if (res.data.data) {
const ibpDatas = JSON.parse(res.data.data).drawData;
this.stationCode = deviceCode;
getIbpInitialState(this.$route.query.group, this.stationCode).then(resp => {
if (resp.data) {
this.statusMessage(resp.data);
this.controlAudio(resp.data.jjtcBuzzer);
}
}).catch(() => {
this.$message.error('获取IBP盘初始状态异常');
});
document.getElementById(this.ibpId).oncontextmenu = function (e) {
return false;
};
this.offsetX = 0;
if (ibpPart === 'left') {
this.offsetX = 0;
} else if (ibpPart === 'right') {
this.offsetX = 1920;
}
const data = parser(ibpDatas, {width: this.canvasWidth, height: this.canvasHeight}); // ibp 绘图编译数据
this.initIbp(this.offsetX);
this.setIbp(data, ibpDatas);
this.$store.dispatch('ibp/setIbpData', ibpDatas);
this.handleBanOpenScreenDoorStatus();
} else {
// 无数据
this.loading = false;
this.$alert('当前ibp盘数据不存在', '信息', {
confirmButtonText: '确定',
callback: action => {}
});
}
} catch (error) {
this.loading = false;
this.$alert('当前ibp盘数据不存在', '信息', {
confirmButtonText: '确定',
callback: action => {}
});
}
window.document.oncontextmenu = function () {
return false;
};
},
setIbp(data, oldData) {
this.$ibp.setIbp(oldData, data);
this.$store.dispatch('ibp/setIbpData', oldData);
},
handleBanOpenScreenDoorStatus() {
this.$store.state.ibp.ibp['keyList'].forEach(item => {
if (item.mean === 'SXYS') {
item.status === 'on' ? this.banDownOpenScreenDoor = false : this.banDownOpenScreenDoor = true;
} else if (item.mean === 'XXYS') {
item.status === 'on' ? this.banUpOpenScreenDoor = false : this.banUpOpenScreenDoor = true;
}
});
},
// 点击选择事件
onSelected(em) {
},
onMouseDown(em) {
if (em.deviceModel.mean) {
if (IbpOperation[em.deviceModel.mean]) {
handlerIbpEvent(this.$route.query.group, IbpOperation[em.deviceModel.mean].event, this.stationCode);
}
}
},
// 右键点击事件
onContextMenu(em) {
this.$store.dispatch('ibp/setUpdateDeviceData', em.eventTarget.model);
},
// 绘图时调用,元素可拖拽
drawIbpInit() {
this.$ibp && this.$ibp.drawIbpInit();
this.showBackButton = false;
},
// 地图可拖拽
setMoveInit(data) {
this.$ibp && this.$ibp.setMoveOnMouseMove(data);
},
// 初始化电子表时间
initClockTime(initTime) {
this.$ibp.initClockTime(initTime);
},
reSize() {
this.width = this.$store.state.config.width;
this.height = this.$store.state.config.height;
this.$ibp && this.$ibp.resize({ width: this.width, height: this.height });
if (!this.size) {
const options = {
scaleRate: this.canvasWidth / 1920,
offsetX: this.offsetX,
offsetY: 0
};
this.$ibp && this.$ibp.setOptions(options);
}
},
setWindowSize() {
const width = this.size ? this.size.width : this.$store.state.app.width;
const height = this.size ? this.size.height : this.$store.state.app.height;
this.$store.dispatch('config/resize', { width: width, height: height });
},
back() {
this.group = this.$route.query.group;
this.$store.dispatch('training/over').then(() => {
if (this.$route.query.projectDevice) {
this.$store.dispatch('LogOut').then(() => {
location.reload();
});
} else {
history.go(-1);
exitFullscreen();
}
});
},
ibpDestroy() {
if (this.$ibp) {
this.$ibp.dispose();
this.$ibp = '';
Vue.prototype.$ibp = '';
}
},
handleViewLoaded() {
this.loading = false;
},
statusMessage(val) {
this.$ibp && this.$ibp.setDeviceStatus(val);
},
async subscribe() {
this.clearSubscribe();
const header = { group: this.$route.query.group || '', 'X-Token': getToken() };
creatSubscribe(`${displayTopic}\/${this.$route.query.group}`, header);
await this.$store.dispatch('training/setHasSubscribed');
},
clearSubscribe() {
clearSubscribe(`${displayTopic}\/${this.$route.query.group}`);
},
controlAudio(val) {
const audio = document.getElementById('buzzer');
// console.log(val, audio);
if (audio !== null) {
if (val) {
audio.play();
} else if (val === false) {
audio.pause();
}
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.ibp-button{
position: absolute;
float: right;
right: 20px;
bottom: 15px;
z-index: 38;
}
.ibp-canvas{
position: absolute;
z-index: 37;
}
</style>