Merge remote-tracking branch 'origin/test'

This commit is contained in:
thesai 2021-08-06 20:46:36 +08:00
commit eed0809f72
53 changed files with 2637 additions and 711 deletions

View File

@ -41,16 +41,19 @@ export default {
}
},
'$store.state.socket.beLogoutCount': async function(val) {
this.$store.dispatch('disconnect').then(()=>{
this.$alert(this.$t('tip.logoutTips'), this.$t('tip.hint'), {
confirmButtonText: this.$t('tip.confirm'),
callback: action => {
this.$store.dispatch('exit').then(resp => {
this.$router.push({path: loginInfo[getSessionStorage('project')].loginPath});
});
}
if (this.$store.state.socket.loggedOutMsg.token === getToken()) {
this.$store.dispatch('disconnect').then(()=>{
this.$alert(this.$t('tip.logoutTips'), this.$t('tip.hint'), {
confirmButtonText: this.$t('tip.confirm'),
callback: action => {
this.$store.dispatch('exit').then(resp => {
this.$router.push({path: loginInfo[getSessionStorage('project')].loginPath});
});
}
});
});
});
}
},
'$store.state.app.transitionAnimationsCount': function(val) {
this.loading = true;

View File

@ -674,3 +674,57 @@ export function noOverlap(mapId) {
method: 'put'
});
}
// 创建进路
export function createRoute(mapId, data) {
return request({
url: `/api/draftMap/${mapId}/route`,
method: 'post',
data
});
}
// 创建延续保护
export function createOverlap(mapId, data) {
return request({
url: `/api/draftMap/${mapId}/overlap`,
method: 'post',
data
});
}
// 创建超限区段
export function createOverrunSection(mapId, data) {
return request({
url: `/api/draftMap/${mapId}/overrun`,
method: 'post',
data
});
}
// 分页查询超限区段
export function queryOverrunSectionPaging(mapId, params) {
return request({
url: `/api/draftMap/${mapId}/overrun/paging`,
method: 'get',
params
});
}
// 更新超限区段
export function updateOverrunSection(mapId, data) {
return request({
url: `/api/draftMap/${mapId}/overrun/${data.code}`,
method: 'put',
data
});
}
// 删除超限区段
export function deleteOverrunSection(mapId, code) {
return request({
url: `/api/draftMap/${mapId}/overrun/${code}`,
method: 'delete'
});
}
// 查询超限区段list
export function queryOverunSectionList(mapId) {
return request({
url: `/api/draftMap/${mapId}/overrun/all`,
method: 'get'
});
}

View File

@ -210,13 +210,13 @@ export function SignalList() {
posx = posx - 7;
}
signaldata.position.set(posx,0,section.railpoint[0].z-3);
signaldata.position.set(posx,0,section.railpoint[0].z-2);
signaldata.rotation.z = ( Math.PI / 2 );
}else if(signaldata.right == true){
if(section.standTrack == true){
posx = posx + 7;
}
signaldata.position.set(posx,0,section.railpoint[0].z+3);
signaldata.position.set(posx,0,section.railpoint[0].z+2);
signaldata.rotation.z = ( - Math.PI / 2 );
}
j = sectiondata.length;

View File

@ -35,7 +35,10 @@ export function Lesson3dPlayer(dom,lessonData,lessonIndex) {
//定义当前课程角色
let nowRole = "";
let oldIndex = 0;
//考试课程
let examList = [];
let examData = {};
//定义场景(渲染容器)
scene = new THREE.Scene();
scene.background = new THREE.Color(0xa0a0a0);
@ -86,20 +89,34 @@ export function Lesson3dPlayer(dom,lessonData,lessonIndex) {
}
this.changeIndex = function(nowIndex){
if(nowIndex!=0){
oldIndex = lessonIndex;
}
if(lessonData.lessonProgress[oldIndex].roleName == nowRole){
updateExam(lessonData.lessonProgress[oldIndex],oldIndex);
}
lessonIndex = nowIndex;
console.log(nowIndex);
scope.nowSceneType = lessonData.lessonProgress[nowIndex].progressScene;
console.log(nowRole);
console.log(lessonData.lessonProgress[lessonIndex].roleName);
// console.log(nowRole);
// console.log(lessonData.lessonProgress[lessonIndex].roleName);
if(lessonData.lessonProgress[lessonIndex].roleName == nowRole){
controlManager.initControlMode(lessonIndex);
controlManager.initRoleMode(true,nowRole);
controlManager.changeIndexEvent(lessonData.lessonProgress[lessonIndex].action,true,assetModelManager.lessonTriggerList[scope.nowSceneType]);
}else{
controlManager.initControlMode(lessonIndex);
controlManager.initRoleMode(false,nowRole);
controlManager.changeIndexEvent(lessonData.lessonProgress[lessonIndex].action,false,assetModelManager.lessonTriggerList[scope.nowSceneType]);
}
if(nowIndex == lessonData.lessonProgress.length-1){
lessonEnd();
}
}
this.changeCameraPos = function(pos){
@ -114,9 +131,29 @@ export function Lesson3dPlayer(dom,lessonData,lessonIndex) {
if(lessonData.lessonProgress[lessonIndex].roleName == nowRole){
roleMode = true;
}
controlManager.initRoleMode(roleMode);
console.log(assetModelManager);
for(let i=0;i<lessonData.lessonProgress.length;i++){
if(nowRole == lessonData.lessonProgress[i].roleName){
examList.push(
{
index:i,
score:10,
isTrue:false,
}
);
}
}
examData = {
allScore:examList.length*10,
lastScore:0,
allStep:examList.length,
trueStep:[],
falseStep:[],
nowStep:0,
time:0,
};
controlManager.initExam(examList,examData);
updataExamStatus(examData);
// if(lessonData.lessonProgress[lessonIndex].action.length>0){
controlManager.changeIndexEvent(lessonData.lessonProgress[lessonIndex].action,roleMode,assetModelManager.lessonTriggerList[scope.nowSceneType]);
@ -126,6 +163,17 @@ export function Lesson3dPlayer(dom,lessonData,lessonIndex) {
// }
};
function updateExam(newIndexData,newIndex){
for(let i=0;i<examList.length;i++){
if(examList[i].index == newIndex){
examData.trueStep.push(newIndexData);
examData.lastScore += 10;
examData.nowStep += 1;
updataExamStatus(examData);
break;
}
}
}
//循环渲染函数
function animate() {

View File

@ -15,6 +15,10 @@ export function ControlManager(dom,scene,lessonData,lessonIndex) {
this.eventHitMode = false;
let nowRole = "";
let roleMode = false;
let examList = {};
let examData = {};
let eventBoxs = [];
let raycasterBoxs = [];
let actionList = [];
@ -108,6 +112,15 @@ export function ControlManager(dom,scene,lessonData,lessonIndex) {
// console.log(roleMode);
};
this.initExam = function(newExamList,newExamData){
examList = newExamList;
examData = newExamData;
};
function updateExam(){
updataExamStatus(examData);
}
const worldOctree = new Octree();
const playerCollider = new Capsule( new THREE.Vector3( 0, 10, 0 ), new THREE.Vector3( 0, 11.9, 0 ), 1 );

View File

@ -145,6 +145,7 @@ class SkinCode extends defaultStyle {
defaultColor: '#FFFFFF', // 信号灯字体默认色
blockColor: '#FFFFFF', // 信号灯字体锁定颜色
checkColor: '#00FF00', // 信号字体
conflictColor:'#FF0000', // 冲突进路始端信号机颜色
nameBorderShow: true // 信号机名字边框显示
},
lamp: {

View File

@ -77,6 +77,7 @@ deviceState[deviceType.Signal] = {
redOpen: 1, // 红灯开放(默认状态)
delayTime: 0, // 信号机延迟解锁倒计时
atsControl: 1, // 0是人工1是自动
checkConflict:0, // 0是不检查冲突1是检测冲突检测冲突进路
fault: 0, // 是否故障
isStartSignal: 0, // 是否进路排列选中始端信号机
isTerminalSignal: 0, // 是否进路排列待选终端信号机
@ -254,5 +255,5 @@ deviceState[deviceType.Train] = {
deviceState[deviceType.Responder] = {
};
deviceState[deviceType.IndicatorLight] = {
}
};
export default deviceState;

View File

@ -568,11 +568,13 @@ class Jlmap {
routeStartSignalData[item.code].forEach((elem, index)=> {
if (index) {
status.atsControl = status.atsControl && elem.atsControl;
status.checkConflict = status.checkConflict || elem.checkConflict;
status.fleetMode = status.fleetMode || elem.fleetMode;
status.ciControl = status.ciControl || elem.ciControl;
status.lock = status.lock || elem.lock;
} else {
status.atsControl = elem.atsControl;
status.checkConflict = elem.checkConflict;
status.fleetMode = elem.fleetMode;
status.ciControl = elem.ciControl;
status.lock = elem.lock;

View File

@ -994,6 +994,7 @@ class Signal extends Group {
!model.atsControl && this.setArtificialRouteClose(); /** 进路交人工控或自动控 */
}
}
// 设置点灯类型 必须在最后设置不能放前面 logicLight 0 物理点灯 1 逻辑点灯
if (model.logicLight) {
this.logicalLight(); // 设置逻辑点灯
@ -1061,6 +1062,11 @@ class Signal extends Group {
if (model.noStatus || model.level === 0) {
this.setAshShow();
}
// 冲突检查状态
if (this.style.Signal.text.conflictColor && model.checkConflict) {
this.sigName.setColor(this.style.Signal.text.conflictColor);
}
}
}

View File

@ -39,9 +39,14 @@
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column prop="status" label="控制状态" width="100">
<el-table-column prop="status" label="控制状态" width="150">
<template slot-scope="scope">
{{ scope.row.atsControl == '0' ? '人工' : '自动' }}
<div v-if="systemName=='xian-01__systerm'">
{{ scope.row.atsControl == '0' ? '人工' : scope.row.checkConflict?'自动 (进行冲突检查)':'自动 (不进行冲突检查)' }}
</div>
<div v-else>
{{ scope.row.atsControl == '0' ? '人工' : '自动' }}
</div>
</template>
</el-table-column>
</el-table>
@ -112,7 +117,7 @@ export default {
},
methods: {
doShow(operate, selected, tempData) {
this.$root.$emit('dialogOpen', selected);
this.$root.$emit('dialogOpen', selected);
this.selected = selected;
//
if (!this.dialogShow) {
@ -142,7 +147,7 @@ export default {
doClose() {
this.loading = false;
this.dialogShow = false;
this.$root.$emit('dialogClose', this.selected);
this.$root.$emit('dialogClose', this.selected);
this.$store.dispatch('training/emitTipFresh');
// mouseCancelState(this.selected);
},

View File

@ -48,6 +48,21 @@
<span :style="{color: scope.row.disabled ? '#CBCBCB':'unset'}">{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column v-if="systemName == 'xian-01__systerm'" prop="atsControl" label="控制状态" style="margin-left:30px">
<template slot-scope="scope">
<span :style="{color: scope.row.disabled ? '#CBCBCB':'unset'}">{{ scope.row.atsControl==0?'人工':'自动' }}</span>
</template>
</el-table-column>
<el-table-column v-if="systemName == 'xian-01__systerm'" prop="conflict" label="冲突检测" style="margin-left:30px">
<template v-if="title == '进路交ATS自动控'&& scope.row.atsControl==0" slot-scope="scope">
<el-checkbox
v-model="checkConflictList[scope.$index].value"
style="text-align: center; display: block;"
/>
<!-- @change="changeCheckConflit(checkConflictMap[scope.row.code],scope.row.code)" -->
<!-- :disabled="scope.row.disabled" -->
</template>
</el-table-column>
<el-table-column v-if="systemName === 'xian-01__systerm'" width="200">
<template slot-scope="scope">
<span :style="{color: scope.row.disabled ? '#CBCBCB':'unset'}">{{ getProtectedSectionName(scope.row) }}</span>
@ -113,6 +128,8 @@ export default {
signalName: '',
allSelect: false,
changeList:[],
checkConflictList:[],
selectedCheckConflict:[],
commitDisabled: true,
disabledLength: 0
};
@ -152,7 +169,12 @@ export default {
if (this.operation == OperationEvent.Signal.humanControl.menu.operation) {
return '进路交人工控';
} else if (this.operation == OperationEvent.Signal.atsAutoControl.menu.operation) {
return '进路交自动控';
if (this.systemName == 'xian-01__systerm') {
return '进路交ATS自动控';
} else {
return '进路交自动控';
}
} else {
return '';
}
@ -171,6 +193,8 @@ export default {
this.selected = selected;
this.allSelect = false;
this.changeList = [];
this.checkConflictList = [];
// .splice(0, this.checkConflictList.length - 1);
this.commitDisabled = true;
this.selection = [];
this.disabledLength = 0;
@ -187,18 +211,28 @@ export default {
}
if (tempData && tempData.length > 0) {
const that = this;
tempData.forEach(elem => {
this.changeList.push(false);
that.changeList.push(false);
elem.disabled = false;
//
if (operate.operation === OperationEvent.Signal.humanControl.menu.operation &&
(elem.atsControl == '0')) {
elem.disabled = true;
this.disabledLength++;
} if (operate.operation === OperationEvent.Signal.atsAutoControl.menu.operation &&
(elem.atsControl == '1')) {
elem.disabled = true;
this.disabledLength++;
that.disabledLength++;
} if (operate.operation === OperationEvent.Signal.atsAutoControl.menu.operation) {
if (elem.atsControl == '1') {
elem.disabled = true;
that.disabledLength++;
that.checkConflictList.push({code:elem.code, value:null});
} else {
if (that.systemName == 'xian-01__systerm') {
that.checkConflictList.push({code:elem.code, value:false});
// that.$set('checkConflictMap', elem.code, );
// that.checkConflictMap[elem.code] = false;
}
}
}
});
}
@ -224,6 +258,16 @@ export default {
this.$store.dispatch('training/emitTipFresh');
// mouseCancelState(this.selected);
},
changeCheckConflit(check, code) {
// debugger;
// this.checkConflictMap;
// this.$set('checkConflictMap', code, check);
// if (check) {
// this.checkConflictMap[code] = false;
// } else {
// this.checkConflictMap[code] = true;
// }
},
changeCheck(check, code) {
if (check) {
this.selection.push(code);
@ -261,9 +305,10 @@ export default {
if (row && row.overlapCode && this.overlapData[row.overlapCode] &&
this.overlapData[row.overlapCode].pathList.length &&
this.overlapData[row.overlapCode].pathList[0].switchPositionList.length) {
const switchDevice = this.$store.getters['map/getDeviceByCode'](this.overlapData[row.overlapCode].pathList[0].switchPositionList[0].switchCode);
const switchLength = this.overlapData[row.overlapCode].pathList[0].switchPositionList.length;
const switchDevice = this.$store.getters['map/getDeviceByCode'](this.overlapData[row.overlapCode].pathList[0].switchPositionList[switchLength - 1].switchCode);
if (switchDevice) {
name = switchDevice.name + (this.overlapData[row.overlapCode].pathList[0].switchPositionList[0].normal ? '定位保护' : '反位保护');
name = switchDevice.name + (this.overlapData[row.overlapCode].pathList[0].switchPositionList[switchLength - 1].normal ? '定位保护' : '反位保护');
}
}
return name;
@ -345,7 +390,7 @@ export default {
operate.message = `命令:进路交人工控<br/>始端信号机:${this.stationName} ${this.signalName}` + msg;
this.$refs.ningBoConfirmTip.doShow(operate);
}
}).catch((error) => {
}).catch(() => {
this.loading = false;
this.doClose();
this.$refs.noticeInfo.doShow();
@ -356,7 +401,7 @@ export default {
if (valid) {
this.doClose();
}
}).catch((error) => {
}).catch(() => {
this.loading = false;
this.doClose();
this.$refs.noticeInfo.doShow();
@ -380,13 +425,22 @@ export default {
operate.message = `命令:进路交自动控<br/>始端信号机:${this.stationName} ${this.signalName}` + msg;
this.$refs.ningBoConfirmTip.doShow(operate);
}
}).catch((error) => {
}).catch(() => {
this.loading = false;
this.doClose();
this.$refs.noticeInfo.doShow();
});
} else {
commitOperate(menuOperate.Signal.atsAutoControl, {routeCodeList:this.selection}, 2, {val}).then(({valid})=>{
const params = {routeCodeList:this.selection};
if (this.systemName === 'xian-01__systerm') {
const checkConflictList = [];
this.selection.forEach(each=>{
const checkConflict = this.checkConflictList.find(check=>{ return check.code == each; });
if (checkConflict) { checkConflictList.push(checkConflict.value); }
});
params.checkConflictList = checkConflictList;
}
commitOperate(menuOperate.Signal.atsAutoControl, params, 2, {val}).then(({valid})=>{
this.loading = false;
if (valid) {
this.doClose();

View File

@ -149,7 +149,12 @@ export const menuOperate = {
signalTotalCancle:{ // 信号机总取消
operation: OperationEvent.Signal.cancelTrainRoute.menu.operation,
cmdType: CMD.Signal.CMD_SIGNAL_TOTAL_CANCLE
},
signalConflictRoute:{ // 冲突进路办理
operation: OperationEvent.Signal.signalConflictRoute.menu.operation,
cmdType:CMD.Signal.CMD_SIGNAL_CONFLICT_ROUTE_SET_CONFIRM
}
// Signal_Conflict_Route_Set_Confirm
},
Switch:{
lock:{

View File

@ -0,0 +1,186 @@
<template>
<div>
<el-dialog
v-dialogDrag
class="conflictRoute"
:class="systemName+' route-hand-control'"
title="冲突进路办理确认"
:visible.sync="show"
width="435px"
:before-close="closeDialog"
:z-index="2000"
:modal="false"
:close-on-click-modal="false"
>
<div>
<div>
<div class="conflictRoute">
<span class="conflictRouteTitle">冲突进路</span>
<span class="conflictRouteName">{{ routeName }}</span>
</div>
</div>
<div class="conflictDescription">冲突描述</div>
<div class="context">
{{ message }}
</div>
<!-- <div class="conflictTips">距离对话框关闭还有{{ minutes }}{{ seconds }}请确认是否办理冲突进路</div> -->
<el-row justify="center" class="button-group">
<el-col :span="7" :offset="3">
<el-button
style="width: 115px;"
:loading="loading"
@click="selectConflict"
>选排冲突进路</el-button>
</el-col>
<!-- :id="domIdConfirm" -->
<!-- :disabled="commitDisabled" -->
<!-- :id="domIdCancel" -->
<el-col :span="7" :offset="3">
<el-button style="width: 115px;" :loading="loading" @click="routeRunplan">按计划执行</el-button>
</el-col>
</el-row>
</div>
</el-dialog>
<notice-info ref="noticeInfo" pop-class="xian-01__systerm" />
</div>
</template>
<script>
import NoticeInfo from '@/jmapNew/theme/components/menus/childDialog/noticeInfo';
import {menuOperate, commitOperate} from '@/jmapNew/theme/components/utils/menuOperate';
export default {
name:'ConflictRoute',
components: {
NoticeInfo
},
props:{
systemName:{
type:String,
required:true
}
},
data() {
return {
dialogShow: false,
message:'',
routeCode:'',
routeName:'',
// allMinutes:10 * 60,
// minutes:10,
// seconds:0,
// inter:null,
loading:false
};
},
computed:{
show() {
return this.dialogShow && !this.$store.state.menuOperation.break;
}
},
methods:{
doShow({route, description}) {
if (route) {
this.routeCode = route.code;
const station = this.$store.getters['map/getDeviceByCode'](route.stationCode);
if (station) {
this.routeName = station.name + ' ' + route.name;
} else {
this.routeName = route.name;
}
}
this.message = description;
this.dialogShow = true;
this.$nextTick(function () {
// this.inter = setInterval(()=>{
// if (this.allMinutes <= 0) {
// clearInterval(this.inter);
// this.routeRunplan();
// }
// this.allMinutes--;
// this.minutes = (this.allMinutes - this.allMinutes % 60) / 60;
// this.seconds = this.allMinutes % 60;
// }, 1000);
this.$store.dispatch('training/emitTipFresh');
});
},
closeDialog() {
const that = this;
// clearInterval(this.inter);
commitOperate(menuOperate.Signal.signalConflictRoute, {routeCode:this.routeCode, way:1}, 3).then(({valid, operate})=>{
if (valid) {
that.doClose();
}
}).catch(error=>{
this.dialogShow = false;
console.error(error);
this.$refs.noticeInfo.doShow();
});
},
doClose() {
this.dialogShow = false;
this.$store.dispatch('training/emitTipFresh');
},
selectConflict() {
this.commit(2);
},
routeRunplan() {
this.commit(1);
},
commit(way) {
this.loading = true;
// int way, 1-2-
commitOperate(menuOperate.Signal.signalConflictRoute, {routeCode:this.routeCode, way:way}, 3).then(({valid, operate})=>{
this.loading = false;
if (valid) {
this.doClose();
// this.$refs.routeControl.doShow(operate, this.selected);
}
}).catch(error=>{
this.loading = false;
console.error(error);
this.$refs.noticeInfo.doShow();
});
}
}
};
</script>
<style>
.conflictRoute .context {
margin:5px 13px 13px 13px;
padding-bottom: 10px !important;
border: 1px solid lightgray;
line-height: 138%;
font-size: 15px;
height:115px;
}
.conflictDescription{
margin-left:13px;
font-size: 15px;
margin-top: 5px;
}
.conflictRoute{
padding-left: 13px;
font-size: 15px;
width: 100%;
padding-right: 13px;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: flex-start;
align-items: flex-start;
}
.conflictRouteName{
font-size: 15px;
height: 23px;
border: 2px inset #E2E2E2;
padding-left: 5px;
flex-grow: 1;
}
.conflictRouteTitle{
}
.conflictTips{
margin-left: 13px;
}
</style>

View File

@ -105,9 +105,10 @@ export default {
if (row && row.overlapCode && this.overlapData[row.overlapCode] &&
this.overlapData[row.overlapCode].pathList.length &&
this.overlapData[row.overlapCode].pathList[0].switchPositionList.length) {
const switchDevice = this.$store.getters['map/getDeviceByCode'](this.overlapData[row.overlapCode].pathList[0].switchPositionList[0].switchCode);
const switchLength = this.overlapData[row.overlapCode].pathList[0].switchPositionList.length;
const switchDevice = this.$store.getters['map/getDeviceByCode'](this.overlapData[row.overlapCode].pathList[0].switchPositionList[switchLength - 1].switchCode);
if (switchDevice) {
name = switchDevice.name + (this.overlapData[row.overlapCode].pathList[0].switchPositionList[0].normal ? '定位保护' : '反位保护');
name = switchDevice.name + (this.overlapData[row.overlapCode].pathList[0].switchPositionList[switchLength - 1].normal ? '定位保护' : '反位保护');
}
}
return name;

View File

@ -9,6 +9,7 @@
<route-hand-control ref="routeHandControl" system-name="xian-01__systerm" />
<route-detail ref="routeDetail" system-name="xian-01__systerm" />
<set-fault ref="setFault" pop-class="xian-01__systerm" />
<conflict-route ref="conflictRoute" system-name="xian-01__systerm" />
</div>
</template>
@ -27,6 +28,7 @@ import MenuContextHandler from '@/scripts/cmdPlugin/MenuContextHandler';
import { mapGetters } from 'vuex';
import { DeviceMenu, OperateMode } from '@/scripts/ConstDic';
import {menuOperate, commitOperate} from '@/jmapNew/theme/components/utils/menuOperate';
import ConflictRoute from './dialog/conflictRoute';
export default {
name: 'SignalMenu',
@ -39,6 +41,7 @@ export default {
RouteHandControl,
RouteDetail,
NoticeInfo,
ConflictRoute,
SetFault
},
props: {
@ -239,18 +242,39 @@ export default {
} else {
this.doClose();
}
},
'$store.state.socket.simulationAlarmInfo': function(val) {
(val || []).forEach(item => {
if (!item.confirmed && !item.recovered) {
if (item.level === '0') {
if (item.type == 'Conflict_Route_Set') {
const route = this.routeList.find(each=>{ return each.code == item.deviceCode; });
this.$refs.conflictRoute.doShow({route:route, description:item.description});
// doShow();
// "":"Route205",
// "description":"(111046(322)[X2112-X2102](311045)(22_G2202)(21_G2102)"
}
}
}
});
}
},
methods: {
initMenu() {
this.menu = MenuContextHandler.covert(this.menuNormal);
//
const menuItem = this.menu.find( item => item.cmdType === CMD.Signal.CMD_SIGNAL_SET_CI_AUTO);
const menuItemDisabled = menuItem.disabled;
menuItem.disabled = true;
const ciAutoMenuItem = this.menu.find( item => item.cmdType === CMD.Signal.CMD_SIGNAL_SET_CI_AUTO);
const ciAutoTriggerMenuItem = this.menu.find( item => item.cmdType === CMD.Signal.CMD_SIGNAL_SET_CI_AUTO_TRIGGER);
const ciAutoMenuItemDisabled = ciAutoMenuItem.disabled;
const ciAutoTriggerMenuItemDisabled = ciAutoTriggerMenuItem.disabled;
ciAutoMenuItem.disabled = true;
ciAutoTriggerMenuItem.disabled = true;
this.routeList.forEach(route => {
if (route.startSignalCode === this.selected.code && route.flt) {
menuItem.disabled = menuItemDisabled;
ciAutoMenuItem.disabled = ciAutoMenuItemDisabled;
}
if (route.startSignalCode === this.selected.code && route.arc ) {
ciAutoTriggerMenuItem.disabled = ciAutoTriggerMenuItemDisabled;
}
});
if (this.operatemode === OperateMode.FAULT) {
@ -299,6 +323,9 @@ export default {
commitOperate(menuOperate.Signal.arrangementRoute, { signalCode: this.selected.code }, 0).then(({valid, operate})=>{
if (valid) {
this.$refs.routeSelection.doShow(operate, this.selected, this.getRouteList(this.selected));
// const route = this.routeList.find(each=>{ return each.code == 'Route205'; });
// this.$refs.conflictRoute.doShow({route:route, description:'(111046(322)[X2112-X2102](311045)(22_G2202)(21_G2102)'});
// this.$refs.conflictRoute.doShow({deviceCode:'Route205', });
}
});
},

View File

@ -126,7 +126,9 @@ export default {
/** 信号机总取消 */
CMD_SIGNAL_TOTAL_CANCLE:{value:'Signal_Total_Cancel', label: '信号机总取消'},
/** 设置保护 */
CMD_SIGNAL_SET_OVERLAP : {value: 'Signal_Set_Overlap', label: '设置保护'}
CMD_SIGNAL_SET_OVERLAP : {value: 'Signal_Set_Overlap', label: '设置保护'},
/** 冲突进路办理 */
CMD_SIGNAL_CONFLICT_ROUTE_SET_CONFIRM:{value: 'Signal_Conflict_Route_Set_Confirm', label: '冲突进路办理'}
},
// 物理区段操作

View File

@ -1703,6 +1703,13 @@ export const OperationEvent = {
operation: '3211',
domId: '_Tips-Signal-setOverlap-Menu{BOTTOM}'
}
},
// 冲突进路办理
signalConflictRoute:{
menu: {
operation: '322',
domId: '_Tips-Signal-conflictRoute-Menu{TOP}'
}
}
},

View File

@ -723,6 +723,7 @@ const map = {
map.stationList.forEach(station => {
if (station.ciStation) {
const centrailzedList = [station.code];
state.stationControlMap[station.code] = centrailzedList;
station.relStationCodeList.forEach(relStationCode => {
state.stationControlMap[relStationCode] = centrailzedList;
if (state.mapDevice[relStationCode].centralized) {

View File

@ -135,6 +135,7 @@ function handle(state, data) {
break;
case 'Be_Logged_Out': // 重复登录被登出
state.beLogoutCount++;
state.loggedOutMsg = msg;
break;
case 'Simulation_Run_Plan_Reload': // 运行图变更
state.runPlanReloadCount++;
@ -342,7 +343,8 @@ const socket = {
simulationSpeed: 1, // 仿真倍速
simulationPause: false,
simulationPslStatus: [], // PSL面板按钮状态信息
simulationPlanChange:{} // 运行图加线/抽线/变化推送消息
simulationPlanChange:{}, // 运行图加线/抽线/变化推送消息
loggedOutMsg: ''
},
getters: {
},

View File

@ -33,7 +33,7 @@
</div>
<Drive-Mmi v-if="mmishow" ref="mmiui" />
<Drive-Tms v-if="tmsshow" />
<Drive-Tms v-if="tmsshow" ref="tmsui"/>
<Drive-Control v-if="dcontrolshow" ref="dcontrol" @warningmsg="warningmsg" @warningmsgoff="warningmsgoff" />
</div>
@ -105,6 +105,9 @@ export default {
if (this.mmishow == true) {
this.$refs.mmiui.updatespeed(newVal);
}
// if(this.tmsshow == true){
// this.$refs.tmsui.updatespeed(newVal);
// }
}
}
},
@ -336,10 +339,14 @@ export default {
// updateDriveValue(this.trainnum);
// }
updatedoorlight(newdata);
console.log(newdata.v);
updatetmsstatus(newdata);
if(this.$refs.mmiui){
this.$refs.mmiui.updatetrainstatus(newdata);
}
updatabuttonlight(newdata);
},
warningmsg(nowmsg){

View File

@ -1,9 +1,210 @@
<template>
<div class = "tmsfault" >
<div class = "tmsvoltage">{{voltage}}</div>
<div class = "tmscurrent">{{current}}</div>
<div class = "tmslevel">{{level}}</div>
<div class = "tmsspeed">{{speed}}</div>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">车号</div></el-col>
<el-col :span="59"><div class="demoCol">1</div></el-col>
<el-col :span="59"><div class="demoCol">2</div></el-col>
<el-col :span="59"><div class="demoCol">3</div></el-col>
<el-col :span="59"><div class="demoCol">4</div></el-col>
<el-col :span="59"><div class="demoCol">5</div></el-col>
<el-col :span="59"><div class="demoCol">6</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">辅助状态</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">辅助ON</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol">辅助OFF</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">辅助ON</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">牵引系统状态</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">58A</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">58A</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">46A</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">57A</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">制动缸压力</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv">0.00</div>
<div class="twodiv">0.00</div>
</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">转向架切除</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="twodiv"></div>
<div class="twodiv"></div>
</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">1侧门</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">1</div>
<div class="fourdiv">3</div>
<div class="fourdiv">5</div>
<div class="fourdiv">7</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">1</div>
<div class="fourdiv">3</div>
<div class="fourdiv">5</div>
<div class="fourdiv">7</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">1</div>
<div class="fourdiv">3</div>
<div class="fourdiv">5</div>
<div class="fourdiv">7</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">8</div>
<div class="fourdiv">6</div>
<div class="fourdiv">4</div>
<div class="fourdiv">2</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">8</div>
<div class="fourdiv">6</div>
<div class="fourdiv">4</div>
<div class="fourdiv">2</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">8</div>
<div class="fourdiv">6</div>
<div class="fourdiv">4</div>
<div class="fourdiv">2</div>
</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">2侧门</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">2</div>
<div class="fourdiv">4</div>
<div class="fourdiv">6</div>
<div class="fourdiv">8</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">2</div>
<div class="fourdiv">4</div>
<div class="fourdiv">6</div>
<div class="fourdiv">8</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">2</div>
<div class="fourdiv">4</div>
<div class="fourdiv">6</div>
<div class="fourdiv">8</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">7</div>
<div class="fourdiv">5</div>
<div class="fourdiv">3</div>
<div class="fourdiv">1</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">7</div>
<div class="fourdiv">5</div>
<div class="fourdiv">3</div>
<div class="fourdiv">1</div>
</div></el-col>
<el-col :span="59"><div class="demoCol">
<div class="fourdiv">7</div>
<div class="fourdiv">5</div>
<div class="fourdiv">3</div>
<div class="fourdiv">1</div>
</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">交流输出电压</div></el-col>
<el-col :span="59"><div class="demoCol">378</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol">--</div></el-col>
<el-col :span="59"><div class="demoCol">-</div></el-col>
<el-col :span="59"><div class="demoCol">-</div></el-col>
<el-col :span="59"><div class="demoCol">378</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">空压机状态</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol"></div></el-col>
<el-col :span="59"><div class="demoCol"></div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">停放制动施加状态</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.85 bar</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.9 bar</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.8 bar</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.85 bar</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.85 bar</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}">7.85 bar</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">HSCB状态</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
</el-row>
<el-row class="demoRow" >
<el-col :span="59"><div class="demoCol">牵引脉冲使能</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol">-- --</div></el-col>
<el-col :span="59"><div class="demoCol" :style="{backgroundColor:'#00ff00',color:'#000'}"></div></el-col>
</el-row>
</div>
</template>
@ -18,10 +219,7 @@ export default {
},
data() {
return {
voltage:"750V",
current:"0A",
level:"",
speed:"km/h",
}
},
mounted() {
@ -48,48 +246,43 @@ export default {
<style rel="stylesheet/scss" lang="scss" scoped>
.tmsfault{
position: absolute;
// border-style:solid;
// border-color: #ffffff;
top:7%;
width:100%;
height:84%;
color:white;
}
.tmsvoltage{
top:7%;
left:3%;
width: 15%;
position: absolute;
top:95px;
left:15px;
width:420px;
height:180px;
text-align: center;
// border-style:solid;
// border-color: #ffffff;
}
.tmscurrent{
top:7%;
left:19%;
width: 15%;
position: absolute;
text-align: center;
// border-style:solid;
// border-color: #ffffff;
.demoRow{
}
.tmslevel{
top:7%;
left:60%;
width: 20%;
position: absolute;
text-align: center;
// border-style:solid;
// border-color: #ffffff;
.demoCol{
width:60px;
height:15px;
color:#fff;
font-size: 9px;
border:solid 1px #fff;
background-color: #000;
}
.tmsspeed{
top:7%;
left:82%;
width: 15%;
position: absolute;
text-align: center;
// border-style:solid;
// border-color: #ffffff;
.twodiv{
width:28.9px;
height:15px;
float:left;
// position: absolute;
border-right:solid 0.5px #fff;
margin: auto;
}
.fourdiv{
width:12px;
height:13px;
margin:1px;
float:left;
// position: absolute;
// border-right:solid 0.5px #fff;
background-color: #00ff00;
color:#000;
}
</style>

View File

@ -1,7 +1,65 @@
<template>
<div class = "tms" :style="{'background-image': 'url('+localStatic+'/jl3d/tms.png)'}" >
<div class = "tmsdiv" >
<div class="tmstopdiv">
<div class="tmstopdivchild" style="left:0">
运行
</div>
<div :id="topmsg.id" class="tmstopdivchild" v-for="(topmsg,index) in trainData" :style="{left:topmsg.left+'px',width:topmsg.width+'px'}">
<div class="tmstopmsg" style="top:0" :style="{width:topmsg.width+'px'}">
{{topmsg.name}}
</div>
<div class="tmstopmsg" style="bottom:0" :style="{width:topmsg.width+'px',color:topmsg.color,backgroundColor:topmsg.bgcolor}">
{{topmsg.value1}}{{topmsg.value2}}
</div>
</div>
<div class="tmstopdivchild" style="right:30px;font-size:10px">
<div id="tmstime" style="width:100%;height:20px;position:absolute;top:0;font-size:10px">
</div>
<div id="tmstimeupdate" style="width:100%;height:20px;position:absolute;bottom:0;font-size:10px">
</div>
</div>
<div class="tmstopdivchild" style="width:30px;right:0px"></div>
</div>
<div style="position:absolute;width:340px;height:25px;left:70px;top:70px;background-repeat:no-repeat;background-size:100% 100%"
:style="{backgroundImage: 'url(' + trainStatusPng + ')' }"/>
<div class="tractionText" :style="{color:trainData[3].bgcolor}">
{{trainData[3].value2}}
</div>
<div style="position:absolute;width:55px;height:150px;right:10px;top:110px;background-repeat:no-repeat;background-size:100% 100%"
:style="{backgroundImage: 'url(' + trainSpeedPng + ')' }">
<div class="tractionPlane" :style="{height:tractionHeight+'px',backgroundColor:trainData[3].bgcolor}"></div>
<div class="speedPlane" :style="{height:speedHeight+'px'}"></div>
</div>
<div class="speedText">
{{trainData[2].value2}}
</div>
<Tms-Fault>
</Tms-Fault>
<div class="tmsdowndiv">
<div class="tmsdowndivmsg" style="top:0;">
<div class="tmsdownbutton"
v-for="(button1,indexbt1) in buttonList1"
:style="{left:button1.left+'px',backgroundColor:button1.bgcolor}">
{{button1.name}}
</div>
</div>
<div class="tmsdowndivmsg" style="bottom:0;border:solid 0.5px #fff">
<div class="tmsdownbutton"
v-for="(button2,indexbt2) in buttonList2"
:style="{left:button2.left+'px',backgroundColor:button2.bgcolor}">
{{button2.name}}
</div>
</div>
</div>
</div>
@ -10,6 +68,8 @@
<script>
import axios from 'axios';
import { prefixIntrger } from '@/utils/date';
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
import TmsFault from '@/views/jlmap3d/drive/sceneview/tmscomponent/tmsfault';
@ -22,6 +82,147 @@ export default {
data() {
return {
localStatic:JL3D_LOCAL_STATIC,
timer: '',
speedHeight:0,
tractionHeight:0,
trainData: [
{
id:"voltage",
width:48,
left:48,
name:"网压",
value1:"",
value2:"1600 V",
color:"#0000FF",
bgcolor:"#000",
},
{
id:"electricity",
width:48,
left:96,
name:"网流",
value1:"",
value2:"317 A",
color:"#0000FF",
bgcolor:"#000",
},
{
id:"v",
width:48,
left:144,
name:"速度",
value1:"",
value2:"0 km/h",
color:"#0000FF",
bgcolor:"#000",
},
{
id:"traction",
width:66,
left:192,
name:"牵引/制动级位",
value1:"",
value2:"0 %",
color:"#fff",
bgcolor:"#000",
},
{
id:"kilm",
width:48,
left:258,
name:"里程标",
value1:"",
value2:"---",
color:"#0000FF",
bgcolor:"#000",
},
{
id:"nextStation",
width:48,
left:306,
name:"下一站",
value1:"",
value2:"XXX",
color:"#0000FF",
bgcolor:"#000",
},
{
id:"lastStation",
width:48,
left:354,
name:"目的站",
value1:"",
value2:"XXX",
color:"#0000FF",
bgcolor:"#000",
}
],
trainStatusPng:JL3D_LOCAL_STATIC+'/jl3d/tms/PMsa2.png',
trainSpeedPng:JL3D_LOCAL_STATIC+'/jl3d/tms/PMS3.png',
buttonList1:[
{
name:"ATO模式",
left:"5",
bgcolor:"#00FF00",
},
{
name:"网络模式",
left:"65",
bgcolor:"#00FF00",
},
{
name:"紧急广播",
left:"245",
bgcolor:"#fff",
},
{
name:"报站设定",
left:"325",
bgcolor:"#fff",
},
],
buttonList2:[
{
name:"主菜单",
left:"5",
bgcolor:"#fff",
},
{
name:"运行",
left:"65",
bgcolor:"#0000FF",
},
{
name:"制动状态",
left:"125",
bgcolor:"#fff",
},
{
name:"牵引状态",
left:"185",
bgcolor:"#fff",
},
{
name:"辅助状态",
left:"245",
bgcolor:"#fff",
},
{
name:"旁路状态",
left:"305",
bgcolor:"#fff",
},
{
name:"空调状态",
left:"365",
bgcolor:"#fff",
},
{
name:"帮助",
left:"425",
bgcolor:"#fff",
}
],
}
},
beforeDestroy() {
@ -29,13 +230,78 @@ export default {
},
watch: {
},
methods: {
'$store.state.training.initTime': function (initTime) {
let date = new Date(initTime);
this.timer = `${prefixIntrger(date.getHours(), 2)}:${prefixIntrger(date.getMinutes(), 2)}:${prefixIntrger(date.getSeconds(), 2)}`;
document.getElementById("tmstimeupdate").innerHTML = this.timer;
}
},
mounted() {
this.time();
window.updatetmsstatus = this.updatetmsstatus;
},
methods: {
time(){
let vDay;
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
let hours = date.getHours();
let minutes = date.getMinutes();
let seconds = date.getSeconds();
document.getElementById("tmstime").innerHTML = year + "/" + month + "/" + day ;
},
updatetmsstatus(newdata){
if(newdata.v || newdata.v == 0){
this.trainData[2].value2 = parseInt(newdata.v)+" km/h";
this.speedHeight = newdata.v/80*149;
}
if(newdata.forcePercent){
// console.log(newdata.forcePercent);
this.trainData[3].value2 = newdata.forcePercent+"%";
this.tractionHeight = newdata.forcePercent/100*149;
}
if(newdata.tow){
if(newdata.tow == "1"){
this.trainData[3].value1 = "牵引 ";
this.trainData[3].color = "#000";
this.trainData[3].bgcolor = "#00FF00";
// this.c1image = this.images.c1["qianyin"];
}
if(newdata.tow == "2"){
// this.c1image = this.images.c1["zhidong"];
this.trainData[3].value1 = "制动 ";
this.trainData[3].color = "#fff";
this.trainData[3].bgcolor = "#FF0000";
}
if(newdata.tow == "3"){
// this.c1image = this.images.c1["duoxing"];
this.trainData[3].value1 = "惰行 ";
this.trainData[3].color = "#fff";
this.trainData[3].bgcolor = "#000";
}
if(newdata.tow == "4"){
// this.c1image = this.images.c1["none"];
this.trainData[3].value1 = "";
this.trainData[3].color = "#fff";
this.trainData[3].bgcolor = "#000";
}
}
if(newdata.nextStation){
this.trainData[5].value2 = newdata.nextStation;
}
if(newdata.endStation){
this.trainData[6].value2 = newdata.endStation;
}
},
},
beforeDestroy() {
}
@ -45,14 +311,101 @@ export default {
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.tms{
.tmsdiv{
width:500px;
height:333px;
background-size:100% 100%;
background-color: #000;
position:absolute;
bottom:0;
left:0;
// border: 0.1px solid #ffffff;
}
.tractionPlane{
width:15px;
position:absolute;
bottom:1px;
left:11px;
background-color: #00ff00;
}
.tractionText{
width:60px;
height:30px;
text-align: center;
position: absolute;
color: #00ff00;
font-size: 12px;
top:90px;
right:0;
}
.speedPlane{
width:15px;
position:absolute;
bottom:1px;
right:11px;
background-color: #00FFFF;
}
.speedText{
width:60px;
height:30px;
text-align: center;
position: absolute;
color: #00FFFF;
font-size: 12px;
top:270px;
right:0;
}
.tmstopdiv{
width:480px;
height:60px;
top:3px;
left:10px;
position: absolute;
text-align: center;
}
.tmstopdivchild{
width:48px;
height:60px;
border:solid 0.5px #fff;
position: absolute;
color:#fff;
}
.tmstopmsg{
// width:100%;
height:50%;
position: absolute;
font-size:10px;
border:solid 0.5px #fff;
// font-weight:30px;
font-weight: 900;
}
.tmsdowndiv{
width:490px;
height:50px;
position:absolute;
text-align: center;
left:5px;
bottom:0;
font-size: 13px;
line-height: 20px;
}
.tmsdowndivmsg{
width:490px;
height:25px;
position:absolute;
}
.tmsdownbutton{
width:55px;
height:20px;
position: absolute;
top:2px;
color:#000;
background-color: #fff;
border:solid 0.5px #fff;
}
</style>

View File

@ -1,18 +1,17 @@
<template>
<div id="lessonprogressdiv" class="lessonprogressdiv">
<div class="progressnum">当前课程页数:{{listLength}}</div>
<el-tabs v-model="activeName" class="activediv" type="card" @tab-click="handleClick">
<el-tab-pane label="课程场景" name="progresslist" >
<draggable v-model="lessonData.lessonData.lessonProgress" group="people" @start="drag=true" @end="drag=false" >
<div class="progressdiv"
:style="{'background-image': 'url('+localstatic+'/lesson3d/sc.png)'}"
v-for="(element,index) in lessonData.lessonData.lessonProgress">
<div class="changeprogressdiv" @click="changeProgressView(index)">{{element.progressName}}</div>
<div class="delprogressdiv" @click="removeProgress(index)" >X</div>
<div class="progressdiv" v-for="(element,index) in lessonData.lessonData.lessonProgress">
<div class="changeprogressdiv" @click="changeProgressView(index)">{{element.progressName}}</div>
<div class="progressdivimg"
:style="{'background-image': 'url('+localstatic+'/lesson3d/sc.png)'}"/>
<div class="delprogressdiv" @click="removeProgress(index)" >删除</div>
</div>
</draggable>
<div class="progressdiv "
<div class="progressdivadd "
:style="{'background-image': 'url('+localstatic+'/lesson3d/addbutton.png)'}"
icon="el-icon-folder-add" @click="addProgress"></div>
</el-tab-pane>
@ -21,10 +20,9 @@
<div class="progressdiv"
v-for="(elementtrigger,indextrigger) in triggerList" :key="elementtrigger.label">
<div class="progressdivimg"
:style="{'background-image': 'url('+localstatic+'/lesson3d/box.png)'}"/>
<div class="progressdivtext" @click="selectModel(elementtrigger)">{{elementtrigger.label}}</div>
<div class="progressassetimg"
:style="{'background-image': 'url('+localstatic+'/lesson3d/box.png)'}"/>
<div class="delprogressdiv" v-if="(elementtrigger.showType == 'loadModel')" @click="deleteModel(elementtrigger)" >删除</div>
</div>
@ -57,7 +55,6 @@
progressList:[
],
listLength:0,
progressIndex:0,
}
},
@ -121,11 +118,7 @@
border:solid 2px #000;
overflow-y: auto;
}
.progressnum{
position: absolute;
right:10px;
top:5px;
}
.progressdiv{
width:80px;
height:100px;
@ -134,13 +127,31 @@
float:left;
border:solid 1px #409EFF;
}
.progressdivadd{
width:80px;
height:80px;
// display:inline;
margin: 20px;
float:left;
border:solid 1px #409EFF;
background-size: 100%;
}
.progressdivimg{
width:80px;
height:60px;
// margin-left: 5px;
// left:5px;
background-size: 100%;
// display:inline;
float:left;
background-repeat: no-repeat;
}
.progressassetimg{
width:70px;
height:70px;
margin-left: 5px;
left:5px;
background-size: 100%;
background-size: 100% ;
// display:inline;
float:left;
}
@ -149,7 +160,7 @@
height:30px;
margin: 0;
// display:inline;
float:left;
float:right;
bottom: 0;
border:solid 1px #409EFF;
font-size: 15px;
@ -157,19 +168,22 @@
.changeprogressdiv{
// position: relative;
width: 100%;
height: 80%;
width:80px;
height:20px;
text-align: center;
float: right;
right: 0;
bottom: 0;
border:solid 2px #000;
border:solid 2px #409EFF;
}
.delprogressdiv{
// position: relative;
width: 20px;
text-align: center;
width: 80px;
height: 20px;
right: 0;
top: 0;
top: bottom;
float: right;
// position:absolute;
border:solid 2px #409EFF;

View File

@ -10,13 +10,6 @@
<div id="" class="lessonsetupdiv" v-show="showSetup">
<div style="text-align:center;top:10%;font-size:30px">课程内容设置</div>
<el-form ref="form" label-width="80px">
<el-form-item label="考试模式">
<el-switch
v-model="examMode"
active-text="开启考试模式"
inactive-text="关闭考试模式">
</el-switch>
</el-form-item>
<el-form-item label="可用角色">
<el-checkbox-group v-model="checkedRole">
@ -82,18 +75,29 @@
当前课程信息
</el-row>
<el-row>
<el-button @click="saveLesson3dData">保存当前课程</el-button>
</el-row>
<el-row>
<el-button @click="setupclick">课程设置</el-button>
</el-row>
<el-row>
<el-button @click="jumpPlayer">预览课程</el-button>
</el-row>
<el-row>
<el-button @click="back">退出编辑器</el-button>
</el-row>
<div class="editmsgdiv">
<el-row>
正在编辑课程页数:{{lessonEditIndex+1}}
</el-row>
<el-row>
课程总页数:{{lessonData.lessonData.lessonProgress.length}}
</el-row>
<el-row>
考试模式:
<el-switch
v-model="examMode"
active-text="开启考试模式"
inactive-text="关闭考试模式">
</el-switch>
</el-row>
</div>
<div class="editmenudiv">
<el-button class="editbutton" @click="saveLesson3dData">保存课程</el-button>
<el-button class="editbutton" @click="setupclick">课程设置</el-button>
<el-button class="editbutton" @click="jumpPlayer">预览课程</el-button>
<el-button class="editbutton" @click="back">退出编辑</el-button>
</div>
</div>
@ -357,16 +361,7 @@
border:solid 2px #000;
}
.lessonsetup {
position: absolute;
width: 15%;
height: 20%;
right:0;
top:0;
border-radius:10px;
border:solid 2px #000;
text-align:center;
}
.el-tabs__content{
position: absolute;
@ -392,4 +387,36 @@
right:0;
bottom:0;
}
.lessonsetup {
position: absolute;
width: 15%;
height: 20%;
right:0;
top:0;
border-radius:10px;
border:solid 2px #000;
text-align:center;
}
.editmsgdiv{
width:100%;
height:40%;
float:left;
border:solid 2px #000;
text-align: left;
}
.editmenudiv{
width:100%;
height:40%;
float:left;
position: relative;
}
.editbutton{
width:44%;
height:42%;
margin:3%;
text-align: center;
float: left;
// position: relative;
}
</style>

View File

@ -1,5 +1,8 @@
<template>
<div class="explainpanediv" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]" @click="selectTool">
<div class="explainpanediv"
v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]"
:style="{'background-image': 'url('+lessonbg+')'}"
@click="selectTool">
<!-- <div class="explainpanetittle" >
{{lessonData.lessonData.lessonProgress[lessonEditIndex].explainPane.tittle}}
</div> -->
@ -32,6 +35,7 @@
return {
localStatic:BASE_ASSET_API,
staticImg:JL3D_LOCAL_STATIC,
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
}
},
computed: {
@ -66,14 +70,13 @@
top:0;
border-radius:10px;
border:solid 2px #000;
background-color: #fff;
color:#000;
color:#fff;
z-index:1;
}
.explainpanetittle{
// height:15%;
text-align: center;
font-size: 20px;
font-size: 25px;
}
.explainpanepic{
@ -89,7 +92,7 @@
position:relative;
left:5%;
width:90%;
font-size: 14px;
font-size: 20px;
// height:20%;
}

View File

@ -1,13 +1,22 @@
<template>
<div class="jobpanediv">
<div class="jobshowbutton" @click="openList">岗位联络</div>
<div class="joblistdiv" v-show="showJobList">
<div class="jobdiv" v-for="(jobitem,index) in jobList" @click="selectJob(jobitem)" >{{jobitem.name}}</div>
<div class="jobshowbutton" @click="openList"
:style="{'background-image': 'url('+lessonbg+')'}"
>岗位联络</div>
<div class="joblistdiv" v-show="showJobList"
:style="{'background-image': 'url('+lessonbg+')'}">
<div class="jobdiv" v-for="(jobitem,index) in jobList" @click="selectJob(jobitem)" >
<img :src="jobpic" />
<div class="jobdivtext" >{{jobitem.name}}</div></div>
</div>
<div class="jobtab" v-if="selectedJob">
<div class="jobtab" v-if="selectedJob"
:style="{'background-image': 'url('+lessonbg+')'}">
<div class="jobtabmsg" >
<div class="jobtabmsgdiv" >{{selectedJob.name}}</div>
<div class="jobtabmsgdiv" >
<img :src="jobpic" />
<div class="jobdivtext" >{{selectedJob.name}}</div>
</div>
<div class="jobtabmsgtext" >{{selectedJob.text}}</div>
</div>
<div class="eltabpaneover" >
@ -48,6 +57,9 @@
showJobList:false,
showJob:false,
selectedJob:null,
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
lkgwbg:JL3D_LOCAL_STATIC+"/lesson3d/lkgw.png",
jobpic:JL3D_LOCAL_STATIC+"/lesson3d/jobpic.png",
}
},
computed: {
@ -130,7 +142,6 @@
left:0;
bottom:0;
border:solid 2px #000;
background-color: #fff;
}
.joblistdiv{
@ -147,11 +158,11 @@
.jobdiv{
width:75px;
height:75px;
height:90px;
margin-top: 5px;
margin-left: 2px;
border:solid 2px #000;
background-color: #fff;
color:#fff;
}
@ -162,7 +173,6 @@
bottom:50px;
width: 300px;
height:450px;
background-color: #fff;
}
.eltabpaneover{
@ -171,7 +181,12 @@
overflow-y:auto;
overflow-x:hidden;
}
.jobdivtext{
// position: absolute;
bottom: 0;
font-size: 13px;
text-align: center;
}
.jobtabmsg{
width:300px;
height:100px;
@ -181,21 +196,21 @@
.jobtabmsgdiv{
width:80px;
height:80px;
height:90px;
position:absolute;
top:10px;
left:5px;
border:solid 2px #000;
background-color: #fff;
color:#fff;
}
.jobtabmsgtext{
width:200px;
height:80px;
height:90px;
// margin-top: 5px;
// margin-left: 2px;
border:solid 2px #000;
background-color: #fff;
color:#fff;
position: absolute;
font-size: 12px;
right:10px;

View File

@ -1,8 +1,9 @@
<template>
<div class="processlogdiv" >
<el-tabs type="border-card">
<el-tab-pane label="进程">
<el-tabs type="border-card"
:style="{'background-image': 'url('+lessonbg+')'}">
<el-tab-pane label="进程" style="overflow-y:auto;">
<div class="processtext" >
{{processText}}
</div>
@ -32,6 +33,7 @@
},
data() {
return {
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
processText:"",
logText:"",
}
@ -78,5 +80,4 @@
font-size: 16px;
}
</style>

View File

@ -1,5 +1,8 @@
<template>
<div class="stepstipsdiv" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]" @click="selectTool">
<div class="stepstipsdiv"
v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]"
@click="selectTool"
:style="{'background-image': 'url('+lessonbg+')'}">
<div class="stepstipstittle" >
{{lessonData.lessonData.lessonProgress[lessonEditIndex].stepTipsData.tittle}}
</div>
@ -21,7 +24,7 @@
},
data() {
return {
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
}
},
computed: {
@ -60,7 +63,6 @@
top:0;
border-radius:10px;
border:solid 2px #000;
background-color: #fff;
z-index:1;
}
.stepstipstittle{

View File

@ -1,17 +1,29 @@
<template>
<div class="toolbardiv" >
<div class="toolbarbutton" @click="openGuide"></div>
<div class="toolbarbutton" @click="openBag"></div>
<div class="toolbarbutton" ></div>
<div class="toolbardiv" :style="{'background-image': 'url('+lessonbg+')'}">
<div class="toolbarbutton"
:style="{'background-image': 'url('+localstatic+'/lesson3d/guide.png)'}"
@click="openGuide"></div>
<div class="toolbarguides" v-show="showGuide">
<div class="toolbarbutton"
:style="{'background-image': 'url('+localstatic+'/lesson3d/bag.png)'}"
@click="openBag"></div>
<div class="toolbarbutton"
:style="{'background-image': 'url('+localstatic+'/lesson3d/back.png)'}">
</div>
<div class="toolbarguides"
:style="{'background-image': 'url('+lessonbg+')'}"
v-show="showGuide">
<div class="toolbarguide" v-for="(guide,index) in guideList">
{{guide.name}}
</div>
</div>
<div class="toolbarbag" v-show="showBag">
<div class="toolbarbag"
:style="{'background-image': 'url('+lessonbg+')'}"
v-show="showBag">
<div class="toolbarplaid" v-for="(tool,index) in toolsList"></div>
</div>
</div>
@ -28,6 +40,8 @@
},
data() {
return {
localstatic:JL3D_LOCAL_STATIC,
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
tipsTittle:"步骤一",
tipsText:"步骤一",
guideList:[],
@ -146,6 +160,7 @@
border-radius:10px;
border:solid 2px #000;
margin: 2px;
background-repeat: no-repeat;
}
.toolbarguides{
@ -157,21 +172,25 @@
overflow-y: auto;
overflow-x: hidden;
border-radius:10px;
color: #fff;
border:solid 2px #000;
text-align: center;
}
.toolbarguide{
margin-top: 5px;
width: 90px;
height: 30px;
border-radius:10px;
border:solid 2px #000;
font-size: 20px;
margin: 5px;
}
.toolbarbag{
position: absolute;
bottom: 80px;
left:0;
top: 80px;
right:0;
width:240px;
height:320px;
overflow-y: auto;

View File

@ -17,6 +17,23 @@
</div>
</div>
<div class="lessontopdiv"
:style="{'background-image': 'url('+lessonbg+')'}">
<div class="lessontopdivtittle"
:style="{'background-image': 'url('+lessonbg+')'}">
课程:{{lessonMsg.lessonTittle}}
</div>
<div class="lessontopdivmsg"
:style="{'background-image': 'url('+lessonbg+')'}">
用户ID:{{lessonMsg.userId}}
</div>
<div class="lessontopdivmsg"
:style="{'background-image': 'url('+lessonbg+')'}"
v-if="lessonMsg.userJob">
当前岗位:{{lessonMsg.userJob}}
</div>
</div>
<div class="lesson3dplayer">
<Step-Tips
:lessonData='lessonData'
@ -53,10 +70,45 @@
@changeCameraPos="changeCameraPos">
</Tool-Bar>
<Result-Tips
:examStatus='examStatus'
ref="rtui">
</Result-Tips>
<div id="lesson3ddraw" class="lesson3ddraw">
</div>
</div>
<div class="lessondowndiv"
:style="{'background-image': 'url('+lessonbg+')'}">
<div class="lessondowndivroommsg"
:style="{'background-image': 'url('+lessonbg+')'}">
房间编号:1
</div>
<div class="lessondowndivmsg"
:style="{'background-image': 'url('+lessonbg+')'}"
v-show = "endExam"
@click="showResult">
考试成绩分析
</div>
<div class="lessondowndivmsg"
:style="{'background-image': 'url('+lessonbg+')'}">
考试计时:{{this.lastPlayTime}}
</div>
<div class="lessondowndivmsg"
:style="{'background-image': 'url('+lessonbg+')'}">
考核步骤:{{examStatus.nowStep}}/{{examStatus.allStep}}
</div>
<div class="lessondowndivmsg"
:style="{'background-image': 'url('+lessonbg+')'}">
考试得分:{{examStatus.lastScore}}/{{examStatus.allScore}}
</div>
</div>
<canvas id="canvastexture" width="128px" height="64px"></canvas>
</div>
@ -66,6 +118,7 @@
import localStore from 'storejs';
// import AssetsModel from '@/views/jlmap3d/lesson3dedit/component/assetsmodel';
import ResultTips from '@/views/jlmap3d/lesson3dplayer/tools/resulttips';
import StepTips from '@/views/jlmap3d/lesson3dplayer/tools/stepstips';
import ProcessLog from '@/views/jlmap3d/lesson3dplayer/tools/processlog';
@ -93,12 +146,34 @@
ProcessLog,
ExplainPane,
JobPane,
ToolBar
ToolBar,
ResultTips
},
data() {
return {
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
staticImg:JL3D_LOCAL_STATIC,
examStatus:{
allScore:0,
nowStep:0,
lastScore:0,
allStep:0,
trueStep:[],
falseStep:[],
time:0,
},
playTime:{
h:0,
m:0,
s:0,
},
time:'',
ms:0,
lastPlayTime:"",
endExam:false,
examResultShow:false,
showSelectJob:true,
lessonMsg:{},
selectJobList:[],
nowRole:"",
jl3d: null,
@ -152,6 +227,8 @@
window.jumpEvent = this.jumpEvent;
window.actionEvent = this.actionEvent;
window.startLesson = this.startLesson;
window.updataExamStatus = this.updataExamStatus;
window.lessonEnd = this.lessonEnd;
this.init(this.$route.query.lessonId);
},
beforeDestroy() {
@ -170,9 +247,15 @@
this.jobPaneData = new JobPaneData();
let loadData;
if(data.data.data){
this.lessonMsg = {
lessonTittle:data.data.name,
userId:data.data.userId,
userJob:"",
};
loadData = JSON.parse(data.data.data);
if(loadData.setup.checkedRole.length == 0){
this.showSelectJob = false;
}
@ -184,26 +267,77 @@
this.lessonData.loadLessonProgress(loadData.lessonProgress);
}else{
this.lessonData.initLessonProgress();
this.$refs.jobpane.initJobList(this.jobPaneData.dataList);
this.jl3d.initNowRole();
}
console.log("loaddata----------------");
console.log(loadData);
// console.log("loaddata----------------");
// console.log(loadData);
// console.log(this.lessonMsg);
this.jl3d = new Lesson3dPlayer(dom,loadData,this.lessonPlayIndex);
}).catch(() => {
});
},
updataExamStatus(newExamStatus){
this.examStatus = newExamStatus;
},
lessonEnd(){
this.endExam = true;
this.showResult();
this.examStatus.time = this.lastPlayTime;
this.stopTime();
},
showResult(){
this.$refs.rtui.showdiv();
},
selectJob(job){
this.showSelectJob = false;
for(let i=0;i<this.jobPaneData.dataList.length;i++){
if(job == this.jobPaneData.dataList[i].name){
this.nowRole = this.jobPaneData.dataList[i].value;
console.log(this.nowRole);
this.lessonMsg.userJob = job;
this.jl3d.initNowRole(this.nowRole);
this.timeStart();
}
}
},
timeStart(){
this.time =setInterval(this.timer,100)
},
timer () {//
this.ms =this.ms +100 //
if (this.ms >=1000) {
this.ms =0
this.playTime.s =this.playTime.s +1 //
}
if (this.playTime.s >=60) {
this.playTime.s =0;
this.playTime.m =this.playTime.m +1 //
}
if (this.playTime.m >=60) {
this.playTime.m;
this.playTime.h =this.playTime.h +1 //
}
this.lastPlayTime =this.toDub(this.playTime.h) +':' +this.toDub(this.playTime.m) +':' +this.toDub(this.playTime.s)/*+""+this.toDubms(this.ms)+"毫秒"*/
},
toDub (n) {//0
if (n <10) {
return '0' + n
}else {
return '' + n
}
},
stopTime () {
clearInterval(this.time);
},
startLesson(){
this.$refs.processlog.startLog();
},
@ -293,6 +427,74 @@
}
.lessontopdiv{
width:100%;
height: 50px;
position: absolute;
top:0;
border-radius:10px;
border:solid 2px #000;
z-index: 10;
color:#fff;
}
.lessontopdivtittle{
width: 33%;
height:50px;
position: absolute;
left:0;
text-align: center;
font-size: 30px;
line-height: 40px;
border-radius:10px;
border:solid 2px #000;
}
.lessontopdivmsg{
width: 20%;
height:49px;
position: relative;
float:right;
text-align: center;
font-size: 18px;
line-height: 40px;
border-radius:10px;
border:solid 2px #000;
}
.lessondowndiv{
width:100%;
height: 40px;
position: absolute;
bottom:0;
border-radius:10px;
border:solid 2px #000;
z-index: 10;
color:#fff;
font-size: 18px;
line-height: 25px;
}
.lessondowndivroommsg{
width: 20%;
height:38px;
position: absolute;
left:0;
text-align: center;
border-radius:10px;
border:solid 2px #000;
}
.lessondowndivmsg{
width: 20%;
height:38px;
position: relative;
float:right;
text-align: center;
border-radius:10px;
border:solid 2px #000;
}
.lesson3ddiv {

View File

@ -1,71 +0,0 @@
<template>
<div class="stepstipsdiv" >
<div class="stepstipstittle" >
{{tipsTittle}}
</div>
<div class="stepstipstext" >
{{tipsText}}
</div>
</div>
</template>
<script>
import Vue from 'vue';
import localStore from 'storejs';
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
//
export default {
name: 'ActionTips',
components: {
},
data() {
return {
tipsTittle:"步骤一",
tipsText:"步骤一",
}
},
computed: {
},
watch: {
},
mounted() {
},
beforeDestroy() {
},
methods: {
},
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.stepstipsdiv {
position: absolute;
width: 20%;
height: 20%;
left:0;
top:0;
border-radius:10px;
border:solid 2px #000;
background-color: #fff;
z-index:1;
}
.stepstipstittle{
text-align: center;
font-size: 20px;
}
.stepstipstext{
font-size: 16px;
}
</style>

View File

@ -54,7 +54,7 @@
// lesson3dSelect('toolproperty','explainpane');
// },
explainJump(){
if(this.lessonData.lessonData.lessonProgress[this.lessonPlayIndex].explainPane.explainPaneType == "jump" || (this.lessonData.lessonData.lessonProgress[this.lessonPlayIndex].explainPane.explainPaneType == "limitjump")){
this.$emit('jumpEvent','jump',this.lessonData.lessonData.lessonProgress[this.lessonPlayIndex].explainPane);
}
@ -69,10 +69,10 @@
@import "src/styles/mixin.scss";
.explainpanediv {
position: absolute;
width: 25%;
height: 25%;
width: 20%;
height: 20%;
left:20%;
top:0;
top:50px;
border-radius:10px;
border:solid 2px #000;
color:#fff;
@ -81,7 +81,7 @@
.explainpanetittle{
// height:15%;
text-align: center;
font-size: 25px;
font-size: 20px;
}
.explainpanepic{
@ -97,7 +97,7 @@
position:relative;
left:5%;
width:90%;
font-size: 20px;
font-size: 18px;
// height:20%;
}

View File

@ -117,7 +117,7 @@
// height: 500px;
min-width: 100px;
left:0;
bottom:0;
bottom:40px;
// border:solid 2px #000;
z-index:1;
}

View File

@ -91,7 +91,7 @@
width: 550px;
height: 350px;
right:0;
bottom:0;
bottom:40px;
border-radius:10px;
z-index:1;
}

View File

@ -0,0 +1,119 @@
<template>
<div class="stepstipsdiv"
:style="{'background-image': 'url('+lessonbg+')'}"
v-show="divshow">
<div class="resultTittleDiv">考试成绩</div>
<div class="resultMsgDiv">
<div v-for="(examItem,index) in examStatus.trueStep" style="width:100%;height:10%">
<div>
{{examItem.explainPane.tittle}}
</div>
<div>
得分:10
</div>
</div>
<div>
总成绩:{{examStatus.lastScore}}
</div>
<div>
考试用时:{{examStatus.time}}
</div>
</div>
<div class="resultCloseDiv" @click="closediv">关闭窗口</div>
</div>
</template>
<script>
import Vue from 'vue';
import localStore from 'storejs';
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
//
export default {
name: 'ResultTips',
props:['examStatus'],
components: {
},
data() {
return {
divshow:false,
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
}
},
computed: {
},
watch: {
},
mounted() {
},
beforeDestroy() {
},
methods: {
showdiv(){
this.divshow = true;
},
closediv(){
this.divshow = false;
},
},
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
.stepstipsdiv {
position: absolute;
width: 60%;
height: 80%;
left:20%;
top:10%;
border-radius:10px;
border:solid 2px #000;
background-color: #fff;
z-index:1;
}
.resultTittleDiv{
width:60%;
height:40px;
font-size: 40px;
color:#fff;
position: absolute;
left:20%;
top:5%;
text-align: center;
}
.resultMsgDiv{
width:90%;
height:70%;
font-size: 20px;
color:#fff;
position: absolute;
left:5%;
top:15%;
border:solid 2px #000;
overflow:auto;
}
.resultCloseDiv{
width:40%;
height:30px;
font-size: 25px;
color:#fff;
position: absolute;
text-align: center;
left:30%;
bottom:5%;
border:solid 2px #000;
}
</style>

View File

@ -60,7 +60,7 @@
width: 20%;
height: 20%;
left:0;
top:0;
top:50px;
border-radius:10px;
border:solid 2px #000;
// background-color: #223458;
@ -70,10 +70,10 @@
}
.stepstipstittle{
text-align: center;
font-size: 25px;
font-size: 20px;
}
.stepstipstext{
font-size: 20px;
font-size: 18px;
}

View File

@ -184,7 +184,7 @@
width: 240px;
height: 80px;
right:0;
top:0;
top:50px;
border-radius:10px;
border:solid 2px #000;
z-index:1;

View File

@ -134,7 +134,10 @@ export default {
return (this.$store.state.training.prdType == '02' || this.isAdmin) && (!this.$route.query.projectDevice);
},
isDISPATCHER() {
return (this.$store.state.training.prdType == '02' || this.isAdmin) && (!this.$route.query.projectDevice || this.project == 'sdy');
console.log("================================");
console.log(this.$store.state.training.prdType);
return (this.$store.state.training.prdType == '01'||this.$store.state.training.prdType == '02' || this.isAdmin) && (!this.$route.query.projectDevice || this.project == 'sdy');
},
isStationSupervisor() {
return this.userRole == 'STATION_SUPERVISOR' && (!this.$route.query.projectDevice || this.project == 'sdy');

View File

@ -16,8 +16,18 @@
<el-radio :label="false">向左</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="延续保护信号机:" prop="signalCode">
<el-select v-model="addModel.signalCode" filterable>
<el-option
v-for="item in signalList"
:key="item.code"
:label="item.name + '(' + item.code + ')'"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="延续保护解锁区段:" prop="unlockSectionCode">
<el-select v-model="addModel.unlockSectionCode" clearable>
<el-select v-model="addModel.unlockSectionCode" filterable>
<el-option
v-for="item in sectionList"
:key="item.code"
@ -196,7 +206,8 @@ export default {
computed: {
...mapGetters('map', [
'switchList',
'sectionList'
'sectionList',
'signalList'
]),
cardTitle() {
if (this.cardMode === 'generate') {
@ -214,6 +225,12 @@ export default {
const baseRules = {
name: [
{ required: true, message: this.$t('rules.pleaseEnterPathName'), trigger: 'blur' }
],
signalCode: [
{ required: true, message: '请选择延续保护信号机', trigger: 'change' }
],
unlockSectionCode: [
{ required: true, message: '请选择延续保护解锁区段', trigger: 'change' }
]
};
return baseRules;

View File

@ -10,9 +10,8 @@
</div>
</template>
<script>
import { putContinueProtect } from '@/api/jmap/mapdraft';
import { putContinueProtect, createOverlap } from '@/api/jmap/mapdraft';
import ProtectOperate from './protect';
import { EventBus } from '@/scripts/event-bus';
export default {
name:'BigRouteInfo',
@ -67,15 +66,19 @@ export default {
},
save() {
const that = this;
that.$refs.form.validate((valid) => {
if (valid) {
console.log('保存');
}
that.$refs.protect.validate((data) => {
data.mapId = this.$route.params.mapId;
createOverlap(this.$route.params.mapId, data).then(res => {
this.$message.success('保存成功!');
this.$refs.protect.clear();
}).catch(() => {
this.$message.error('保存失败!');
});
});
},
clear() {
if (this.$refs && this.$refs.form && this.mapInfo) {
this.$refs.form.resetFields();
if (this.$refs && this.$refs.protect && this.mapInfo) {
this.$refs.protect.resetFields();
}
},
update() {
@ -84,7 +87,7 @@ export default {
this.$message.success('更新成功!');
this.$refs.protect.clear();
this.isModify = false;
EventBus.$emit('successCI');
// EventBus.$emit('successCI');
}).catch(() => {
this.$message.error('更新失败!');
});

View File

@ -41,6 +41,7 @@ import FlankProtectOperate from './flankProtectOperate/index';
import DwellTimeOperate from './dwellTimeOperate/index';
import DestinationOperate from './destinationOperate/index';
import ContinueProtectOperate from './continueProtectOperate/index';
import OverrunSectionOperate from './overrunSectionOperate/index';
export default {
name: 'DataRelation',
@ -110,7 +111,8 @@ export default {
{label: this.$t('map.automaticSignal'), name:'automatic', menus:AutomaticOperate},
{label: this.$t('map.routing'), name:'routing', menus:RoutingOperate},
{label: '停站时间', name:'dwellTime', menus:DwellTimeOperate},
{label: '设置运行等级', name:'runLevel', menus:RunLevelOperate}
{label: '设置运行等级', name:'runLevel', menus:RunLevelOperate},
{label: '超限区段', name: 'overrun', menus: OverrunSectionOperate }
// ]
];
this.enabledTab = 'route';

View File

@ -0,0 +1,223 @@
<template>
<div v-show="show">
<el-dialog v-dialogDrag v-loading="loading" title="超限区段预览" :visible.sync="show" width="95%" top="1vh" class="dialog_content_box" :before-do-close="doClose" append-to-body>
<div>
<QueryListPage
ref="queryListPage"
:pager-config="pagerConfig"
:query-form="queryForm"
:query-list="queryList"
/>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { queryOverrunSectionPaging, deleteOverrunSection} from '@/api/jmap/mapdraft';
// import ProtectDetail from './protectDetail';
export default {
name: 'RouteDetail',
props: {
mapInfo: {
type: Object,
default() {
return null;
}
},
overlapList: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
show: false,
loading: false,
pagerConfig: {
pageSize: 'pageSize',
pageIndex: 'pageNum'
},
queryForm: {
labelWidth: '120px',
queryObject: {
sectionCode: {
type: 'select',
label: '区段',
config: {
data: []
}
},
ciSwitchCode: {
type: 'select',
label: '道岔',
config: {
data: []
}
},
switchCode: {
type: 'select',
label: '防护道岔',
config: {
data: []
}
}
}
}
};
},
computed: {
...mapGetters('map', [
'switchList',
'sectionList'
]),
queryList() {
return {
query: this.queryFunction,
selectCheckShow: false,
indexShow: true,
columns: [
{
title: this.$t('map.code'),
prop: 'code',
width: 150
},
{
title: '区段',
prop: 'sectionCode',
type: 'tag',
columnValue: (row) => { return this.$convertField(row.sectionCode, this.sectionList, ['code', 'name']); },
tagType: (row) => { return ''; }
},
{
title: '道岔',
prop: 'ciSwitch',
type: 'tag',
columnValue: (row) => { return row.ciSwitch ? this.$convertField(row.ciSwitch.switchCode, this.switchList, ['code', 'name']) : ''; },
tagType: (row) => { return ''; }
},
{
title: '道岔位置',
type: 'tag',
prop: 'ciSwitch',
columnValue: (row) => { return row.ciSwitch ? (row.ciSwitch.normal ? '定位' : '反位') : ''; },
tagType: (row) => { return ''; }
},
{
title: '防护的道岔',
type: 'tag',
prop: 'switchCode',
columnValue: (row) => { return this.$convertField(row.switchCode, this.switchList, ['code', 'name']); },
tagType: (row) => { return ''; }
},
{
type: 'button',
title: this.$t('map.operation'),
width: '250',
buttons: [
{
name: this.$t('map.compile'),
handleClick: this.edit
},
{
name: this.$t('map.deleteObj'),
handleClick: this.deleteObj,
type: 'danger'
}
]
}
]
};
}
},
watch: {
sectionList: function (val, old) {
this.initQueryObjectSectionList(val);
},
switchList: function (val, old) {
this.initQueryObjectSwitchList(val);
}
},
mounted() { //
},
methods: {
initQueryObjectSectionList(val) {
const list = [];
if (val && val.length) {
for (let i = 0; i < val.length; i++) {
list.push({ label: `${val[i].name}(${val[i].code})`, value: val[i].code });
}
}
this.queryForm.queryObject.sectionCode.config.data = list;
},
initQueryObjectSwitchList(val) {
const list = [];
if (val && val.length) {
for (let i = 0; i < val.length; i++) {
list.push({ label: `${val[i].name}(${val[i].code})`, value: val[i].code });
}
}
this.queryForm.queryObject.switchCode.config.data = list;
this.queryForm.queryObject.ciSwitchCode.config.data = list;
},
doShow() {
this.show = true;
this.$nextTick(() => {
this.initQueryObjectSectionList(this.sectionList);
this.initQueryObjectSwitchList(this.switchList);
this.$refs.queryListPage && this.$refs.queryListPage.commitQuery();
});
},
doClose() {
this.show = false;
},
queryFunction(params) {
if (this.mapInfo && this.mapInfo.id) {
return queryOverrunSectionPaging(this.mapInfo.id, params);
}
},
edit(index, row) {
this.$emit('routeSelected', row);
this.doClose();
},
deleteObj(index, row) {
if (row) {
this.$confirm('是否确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteOverrunSection(this.$route.params.mapId, row.code).then(response => {
this.reloadTable();
}).catch(() => {
this.$messageBox('删除失败');
});
}).catch(() => {
this.$message.info('已取消删除');
});
}
},
reloadTable() {
if (this.queryList && this.queryList.reload) {
this.queryList.reload();
}
},
selectedObj(index, row) {
this.$emit('setRouteCode', row);
this.show = false;
}
}
};
</script>
<style lang="scss">
.dialog_content_box{
.el-dialog__body{
padding-top: 3px;
}
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<div>
<overrun-detail ref="overrunDetail" :map-info="mapInfo" @routeSelected="routeSelected" />
<overrun-form
ref="overrunForm"
:map-info="mapInfo"
:selected="selected"
:overrun-data="overrunData"
@setCenter="setCenter"
/>
</div>
</template>
<script>
import OverrunDetail from './detail';
import OverrunForm from './overrun';
export default {
name: 'Index',
components: {
OverrunDetail,
OverrunForm
},
props: {
mapInfo: {
type: Object,
default() {
return null;
}
},
selected: {
type: Object,
default() {
return null;
}
}
},
data() {
return {
overrunData: null
};
},
methods: {
setCenter(code) {
this.$emit('setCenter', code);
},
routeSelected(data) {
this.overrunData = data;
if (this.$refs && this.$refs.overrunForm) {
this.$refs.overrunForm.isSave = !data.id;
}
},
previewRouteEvent: function () {
if (this.$refs && this.$refs.overrunDetail) {
this.$refs.overrunDetail.doShow();
}
},
setSelected(selected) {
this.$refs.overrunForm.setSelected(selected);
}
}
};
</script>
<style scoped>
</style>

View File

@ -0,0 +1,262 @@
<template>
<div style="height: 100%;" class="route_box_list">
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-form ref="form" :model="addModel" :rules="rules" label-width="190px" size="mini">
<el-form-item label="区段" prop="sectionCode">
<el-select v-model="addModel.sectionCode" clearable filterable>
<el-option
v-for="item in sectionList"
:key="item.code"
:label="item.name + ' (' + item.code+ ')'"
:value="item.code"
/>
</el-select>
<el-button
:type=" field === 'overrunSection' ? 'danger' : 'primary'"
@click="hover('overrunSection')"
>{{ $t('map.activate') }}</el-button>
</el-form-item>
<el-form-item label="道岔" prop="ciSwitch.switchCode">
<el-select v-model="addModel.ciSwitch.switchCode" clearable filterable>
<el-option
v-for="item in switchList"
:key="item.code"
:label="item.name + ' (' + item.code+ ')'"
:value="item.code"
/>
</el-select>
<el-button
:type=" field === 'overrunSwitch' ? 'danger' : 'primary'"
@click="hover('overrunSwitch')"
>{{ $t('map.activate') }}</el-button>
</el-form-item>
<el-form-item label="道岔位置" prop="ciSwitch.normal">
<el-select v-model="addModel.ciSwitch.normal">
<el-option
v-for="item in SwitchLocateTypeList"
:key="item.code"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="防护道岔" prop="switchCode">
<el-select v-model="addModel.switchCode" clearable filterable>
<el-option
v-for="item in switchList"
:key="item.code"
:label="item.name + '(' + item.code + ')'"
:value="item.code"
/>
</el-select>
<el-button
:type=" field === 'protectiveSwitch' ? 'danger' : 'primary'"
@click="hover('protectiveSwitch')"
>{{ $t('map.activate') }}</el-button>
</el-form-item>
</el-form>
<br>
<div class="draft">
<el-button-group>
<el-button v-if="isSave" type="primary" size="small" :loading="loading" @click="save">保存超限区段</el-button>
<el-button v-else type="warning" size="small" :loading="loading" @click="update">修改超限区段</el-button>
</el-button-group>
</div>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { updateOverrunSection, createOverrunSection } from '@/api/jmap/mapdraft';
export default {
name: 'RouteOperation',
props: {
selected: {
type: Object,
default() {
return null;
}
},
mapInfo: {
type: Object,
default() {
return null;
}
},
overrunData: {
type: Object,
default() {
return null;
}
}
},
data() {
var validateSection = (rule, value, callback) => {
if (!value && !this.addModel.ciSwitch.switchCode) {
callback(new Error('区段和道岔必须选填其一'));
} else {
if (!this.addModel.ciSwitch.switchCode) {
this.$refs.form.validateField('ciSwitch.switchCode');
}
callback();
}
};
var validateSwitch = (rule, value, callback) => {
if (!value && !this.addModel.sectionCode) {
callback(new Error('区段和道岔必须选填其一'));
} else {
if (!this.addModel.sectionCode) {
this.$refs.form.validateField('sectionCode');
}
callback();
}
};
return {
isSave: true,
field: '',
loading: false,
SwitchLocateTypeList: [
{ name: '定位', code: true },
{ name: '反位', code: false }
],
addModel: {
mapId: '',
code: '',
sectionCode: '',
ciSwitch: {
switchCode: '',
normal: true
},
switchCode: ''
},
rules: {
sectionCode: [
{ validator: validateSection, trigger: 'change' }
],
'ciSwitch.switchCode': [
{ validator: validateSwitch, trigger: 'change' }
]
}
};
},
computed: {
...mapGetters('map', [
'switchList',
'sectionList'
])
},
watch: {
mapInfo(val) {
if (val) {
this.addModel.mapId = val.id;
}
},
overrunData(val, old) {
if (val) {
this.addModel = {
mapId: val.mapId,
code: val.code,
sectionCode: val.sectionCode,
ciSwitch: val.ciSwitch ? val.ciSwitch : { switchCode: '', normal: true },
switchCode: val.switchCode
};
}
}
},
mounted() {
},
methods: {
deviceChange(code) {
this.$emit('setCenter', code);
},
hover(field) {
this.field = field === this.field ? '' : field;
},
save() {
// console.log('');createRoute
this.$refs.form.validate((valid) => {
if (valid) {
const modle = {
mapId: this.mapInfo.id,
code: '',
sectionCode: this.addModel.sectionCode,
ciSwitch: this.addModel.ciSwitch.switchCode ? this.addModel.ciSwitch : null,
switchCode: this.addModel.switchCode
};
createOverrunSection(this.mapInfo.id, modle).then(res => {
this.$message.success('保存超限区段成功!');
this.clear();
}).catch(() => {
this.$message.error('保存超限区段失败!');
});
}
});
},
update() {
this.$refs.form.validate((valid) => {
if (valid) {
const modle = {
mapId: this.mapInfo.id,
code: this.addModel.code,
sectionCode: this.addModel.sectionCode,
ciSwitch: this.addModel.ciSwitch.switchCode ? this.addModel.ciSwitch : null,
switchCode: this.addModel.switchCode
};
updateOverrunSection(this.mapInfo.id, modle).then(res => {
this.$message.success('更新超限区段成功!');
this.clear();
}).catch(() => {
this.$message.error('更新超限区段失败!');
});
}
});
},
clear() {
if (this.$refs && this.$refs.form && this.mapInfo) {
delete this.addModel.id;
this.$refs.form.resetFields();
this.addModel.mapId = this.mapInfo.id;
this.addModel.sectionCode = '';
this.addModel.ciSwitch = { switchCode: '', normal: true };
this.addModel.switchCode = '';
}
},
setSelected(selected) {
if (selected) {
if (selected._type.toUpperCase() === 'Section'.toUpperCase() && selected._type !== '02' && this.field.toUpperCase() === 'overrunSection'.toUpperCase()) {
this.addModel.sectionCode = selected.code;
} else if (selected._type.toUpperCase() === 'Switch'.toUpperCase() && this.field.toUpperCase() === 'overrunSwitch'.toUpperCase()) {
this.addModel.ciSwitch.switchCode = selected.code;
} else if (selected._type.toUpperCase() === 'Switch'.toUpperCase() && this.field.toUpperCase() === 'protectiveSwitch'.toUpperCase()) {
this.addModel.switchCode = selected.code;
}
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
/deep/ .el-radio {
margin-right: 10px;
}
/deep/ {
.el-select .el-tag {
height: auto;
display: flex;
align-items: center;
justify-content: center;
padding-right: 15px;
box-sizing: border-box;
white-space: normal;
}
.el-input__suffix{
right: 2px;
}
.draft {
width: 400px;
text-align: center;
margin: 20px auto;
}
}
</style>

View File

@ -149,6 +149,16 @@
@click="hover('routeStationStandList')"
>{{ $t('map.activate') }}</el-button>
</el-form-item>
<el-form-item label="关联超限区段" prop="overrunList">
<el-select v-model="addModel.overrunList" multiple clearable filterable style="width: 220px;">
<el-option
v-for="item in overrunSectionList"
:key="item.code"
:label="getOverrunName(item)"
:value="item.code"
/>
</el-select>
</el-form-item>
</el-form>
<hostile-data ref="hostile" :conflicting-signal-list="addModel.conflictingSignalList" @hover="hover" />
<br>
@ -164,7 +174,7 @@
</template>
<script>
import { mapGetters } from 'vuex';
import { getRouteNewList, getFlankProtectionList, putSetDraftMapRouteById } from '@/api/jmap/mapdraft';
import { getRouteNewList, getFlankProtectionList, putSetDraftMapRouteById, createRoute, queryOverunSectionList } from '@/api/jmap/mapdraft';
import HostileData from './hostileData';
// import { EventBus } from '@/scripts/event-bus';
@ -232,9 +242,11 @@ export default {
flankProtectionList: [],
stationStandList: [], //
overlapCode:'',
overrunList: [], //
conflictingSignalList: [] //
},
// overlapList: [], //
overrunSectionList: [], //
routeList: [] //
};
},
@ -343,6 +355,7 @@ export default {
mounted() {
this.getRouteList();
this.getFlankProtectList();
this.getOverrunSectionList();
// this.initProtectData();
// EventBus.$on('successCI', () => {
// this.initProtectData();
@ -354,6 +367,17 @@ export default {
return station.ciStation;
});
},
getOverrunName(overrun) {
if (overrun.ciSwitch && overrun.ciSwitch.switchCode) {
const switchDevice = this.$store.getters['map/getDeviceByCode'](overrun.ciSwitch.switchCode);
return switchDevice ? overrun.code + '(' + switchDevice.name + '-' + (overrun.ciSwitch.normal ? '定位' : '反位') + ')' : overrun.code;
} else if (overrun.sectionCode) {
const section = this.$store.getters['map/getDeviceByCode'](overrun.sectionCode);
return section ? overrun.code + '(' + section.name + ')' : overrun.code;
} else {
return overrun.code;
}
},
async getRouteList() {
const response = await getRouteNewList(this.$route.params.mapId, { pageSize: 9999, pageNum: 1 });
this.routeList = response.data.list;
@ -364,6 +388,11 @@ export default {
this.$store.dispatch('map/setFlankProtectList', item);
});
},
getOverrunSectionList() {
queryOverunSectionList(this.$route.params.mapId).then(resp => {
this.overrunSectionList = resp.data;
});
},
swictchName(code) {
let name = '';
if (code) {
@ -400,7 +429,18 @@ export default {
return model;
},
save() {
console.log('暂无接口');
// console.log('');createRoute
this.$refs.form.validate((valid) => {
if (valid) {
this.addModel.mapId = this.mapInfo.id;
createRoute(this.mapInfo.id, this.addModel).then(res => {
this.$message.success('保存进路成功!');
this.clear();
}).catch(() => {
this.$message.error('保存进路失败!');
});
}
});
},
update() {
this.$refs.form.validate((valid) => {
@ -425,6 +465,7 @@ export default {
this.addModel.overlapCode = '';
this.addModel.code = '';
this.addModel.conflictingSignalList = [];
this.addModel.overrunList = [];
this.isSave = true;
this.routeCode = '';
this.routeType = '';

View File

@ -50,9 +50,6 @@ export default {
if (this.type == 'Text') {
data.content = `${this.editModel.prepend}::${this.editModel.content}`;
}
if (data.type !== 'VB') {
data.signalCode = '';
}
this.$emit('updateMapModel', data);
this.$emit('clearDeviceSelect');
} else {

View File

@ -8,7 +8,7 @@
:centralized-station-list="centralizedStationList"
:responder-list="responderList"
:section-list="filterSectionList"
:signalList="signalList"
:signal-list="signalList"
v-on="$listeners"
@hover="hover"
@deviceChange="deviceChange"
@ -31,24 +31,25 @@
/>
</el-tab-pane> -->
<el-tab-pane class="view-control" label="批量创建" name="third" :lazy="lazy">
<responder-batch
<responder-batch
ref="respBatch"
:field="field"
:responder-type-list="responderTypeList"
:centralized-station-list="centralizedStationList"
:responder-list="responderList"
:section-list="filterSectionList"
:signalList="signalList"
:signal-list="signalList"
v-on="$listeners"
@hover="hover"
@deviceChange="deviceChange"
@deviceSelect="deviceSelect" />
@deviceSelect="deviceSelect"
/>
</el-tab-pane>
<el-tab-pane class="view-control" label="批量操作" name="fourth" :lazy="lazy">
<responder-batch-operate
<responder-batch-operate
:responder-list="responderList"
:signal-list="signalList"
/>
/>
</el-tab-pane>
</el-tabs>
</template>
@ -88,8 +89,8 @@ export default {
computed: {
...mapGetters('map', [
'stationList',
'sectionList',
'signalList',
'sectionList',
'signalList',
'responderList'
]),
filterSectionList() {
@ -132,18 +133,18 @@ export default {
this.$emit('deviceSelect', '');
} else {
this.$message.error('请选择物理区段');
}
}
} else if (selected && selected._type.toUpperCase() === 'Signal'.toUpperCase() && this.field.toUpperCase() === 'RelModelSignalCode'.toUpperCase()) {
this.$refs.respModel.setModelProp(selected, 'signalCode');
this.activeName = 'first';
this.field = '';
this.$emit('deviceSelect', '');
this.$refs.respModel.setModelProp(selected, 'signalCode');
this.activeName = 'first';
this.field = '';
this.$emit('deviceSelect', '');
} else if (selected && selected._type.toUpperCase() === 'Signal'.toUpperCase() && this.field.toUpperCase() === 'RelSignalCode'.toUpperCase()) {
this.$refs.respCreate.setModelProp(selected, 'signalCode');
this.activeName = 'second';
this.field = '';
this.$emit('deviceSelect', '');
this.$refs.respCreate.setModelProp(selected, 'signalCode');
this.activeName = 'second';
this.field = '';
this.$emit('deviceSelect', '');
} else if (selected && selected._type.toUpperCase() === 'Section'.toUpperCase() && this.field.toUpperCase() === 'RelSectionCode'.toUpperCase()) {
if (['01', '03'].includes(selected.type)) {
this.$refs.respCreate.setModelProp(selected, 'sectionCode');
@ -154,10 +155,10 @@ export default {
this.$message.error('请选择物理区段');
}
} else if (selected && selected._type.toUpperCase() === 'Signal'.toUpperCase() && this.field.toUpperCase() === 'RelBatchSignalCode'.toUpperCase()) {
this.$refs.respBatch.setModelProp(selected, 'signalCode');
this.activeName = 'third';
this.field = '';
} else if (selected && selected._type.toUpperCase() === 'Section'.toUpperCase() && this.field.toUpperCase() === 'RelBatchSectionCode'.toUpperCase()) {
this.$refs.respBatch.setModelProp(selected, 'signalCode');
this.activeName = 'third';
this.field = '';
} else if (selected && selected._type.toUpperCase() === 'Section'.toUpperCase() && this.field.toUpperCase() === 'RelBatchSectionCode'.toUpperCase()) {
if (['01', '03'].includes(selected.type)) {
this.$refs.respBatch.setModelProp(selected, 'sectionCode');
this.activeName = 'third';
@ -169,17 +170,17 @@ export default {
} else if (!selected) {
this.$emit('deviceSelect', '');
}
},
edit() {
if (this.$refs.respModel) {
this.$refs.respModel.edit()
}
},
deleteObj() {
if (this.$refs.respModel) {
this.$refs.respModel.deleteObj()
}
}
},
edit() {
if (this.$refs.respModel) {
this.$refs.respModel.edit();
}
},
deleteObj() {
if (this.$refs.respModel) {
this.$refs.respModel.deleteObj();
}
}
}
};
</script>

View File

@ -1,314 +1,318 @@
<template>
<el-form
ref="form"
label-width="90px"
:model="formData"
size="mini"
:rules="formRules"
>
<el-row>
<el-col :span="24">
<el-form-item label="区段" prop="sectionCode">
<el-select
v-model="formData.sectionCode"
filterable
class="responderSet"
placeholder="请选择"
>
<el-option
v-for="item in sectionList"
:key="item.code"
:label="item.name + '(' + item.code + ')'"
:value="item.code"
/>
</el-select>
<el-button
@click="handleHover(-1, 'RelBatchSectionCode')"
:type="
field === 'RelBatchSectionCode' && row === -1
? 'danger'
: 'primary'
"
>
激活
</el-button>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型" prop="type">
<el-select
v-model="formData.type"
filterable
class="responderSet"
placeholder="请选择"
@change="changeSubFormType"
>
<el-option
v-for="item in responderTypeList"
:key="item.value"
:label="`${item.name}(${item.value})`"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="创建数量" prop="count">
<el-input
v-model="formData.count"
class="responderSet"
placeholder="请输入数量"
type="number"
min="1"
max="10"
@blur="numBlur"
/>
</el-form-item>
</el-col>
</el-row>
<div class="sub-form" v-if="subFormData.length">
<template v-for="(item, index) in subFormData">
<div :key="`subFormUnit${index}`" class="sub-form-unit">
<el-row>
<el-col :span="10">
<el-form-item label="名称">
<el-input
v-model="item.name"
placeholder="请输入名称"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类型">
<el-select
v-model="item.type"
filterable
placeholder="请选择类型"
>
<el-option
v-for="opt in responderTypeList"
:key="opt.value"
:label="`${opt.name}(${opt.value})`"
:value="opt.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<el-form-item label="区段偏移值">
<el-input-number v-model="item.offset" />
</el-form-item>
</el-col>
<el-col :span="14" v-if="item.type === 'VB'">
<el-form-item label="信号机">
<el-select
v-model="item.signalCode"
filterable
placeholder="请选择信号机"
>
<el-option
v-for="opt in signalList"
:key="opt.code"
:label="`${opt.name}(${opt.code})`"
:value="opt.code"
/>
</el-select>
<el-button
@click="
handleHover(index, 'RelBatchSignalCode')
"
:type="
field === 'RelBatchSignalCode' &&
row === index
? 'danger'
: 'primary'
"
>
激活
</el-button>
</el-form-item>
</el-col>
</el-row>
</div>
</template>
</div>
<div class="btn-area">
<el-button size="small" type="primary" @click="doBatchCreate"
>批量创建</el-button
>
<el-button size="small" type="danger" @click="resetForm"
>重置</el-button
>
</div>
</el-form>
<el-form
ref="form"
label-width="90px"
:model="formData"
size="mini"
:rules="formRules"
>
<el-row>
<el-col :span="24">
<el-form-item label="区段" prop="sectionCode">
<el-select
v-model="formData.sectionCode"
filterable
class="responderSet"
placeholder="请选择"
>
<el-option
v-for="item in sectionList"
:key="item.code"
:label="item.name + '(' + item.code + ')'"
:value="item.code"
/>
</el-select>
<el-button
:type="
field === 'RelBatchSectionCode' && row === -1
? 'danger'
: 'primary'
"
@click="handleHover(-1, 'RelBatchSectionCode')"
>
激活
</el-button>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型" prop="type">
<el-select
v-model="formData.type"
filterable
class="responderSet"
placeholder="请选择"
@change="changeSubFormType"
>
<el-option
v-for="item in responderTypeList"
:key="item.value"
:label="`${item.name}(${item.value})`"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="创建数量" prop="count">
<el-input
v-model="formData.count"
class="responderSet"
placeholder="请输入数量"
type="number"
min="1"
max="10"
@blur="numBlur"
/>
</el-form-item>
</el-col>
</el-row>
<div v-if="subFormData.length" class="sub-form">
<template v-for="(item, index) in subFormData">
<div :key="`subFormUnit${index}`" class="sub-form-unit">
<el-row>
<el-col :span="10">
<el-form-item label="名称">
<el-input
v-model="item.name"
placeholder="请输入名称"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类型">
<el-select
v-model="item.type"
filterable
placeholder="请选择类型"
>
<el-option
v-for="opt in responderTypeList"
:key="opt.value"
:label="`${opt.name}(${opt.value})`"
:value="opt.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<el-form-item label="区段偏移值">
<el-input-number v-model="item.offset" />
</el-form-item>
</el-col>
<el-col v-if="item.type === 'VB'" :span="14">
<el-form-item label="信号机">
<el-select
v-model="item.signalCode"
filterable
placeholder="请选择信号机"
>
<el-option
v-for="opt in signalList"
:key="opt.code"
:label="`${opt.name}(${opt.code})`"
:value="opt.code"
/>
</el-select>
<el-button
:type="
field === 'RelBatchSignalCode' &&
row === index
? 'danger'
: 'primary'
"
@click="
handleHover(index, 'RelBatchSignalCode')
"
>
激活
</el-button>
</el-form-item>
</el-col>
</el-row>
</div>
</template>
</div>
<div class="btn-area">
<el-button
size="small"
type="primary"
@click="doBatchCreate"
>批量创建</el-button>
<el-button
size="small"
type="danger"
@click="resetForm"
>重置</el-button>
</div>
</el-form>
</template>
<script>
import * as utils from "./utils";
import * as utils from './utils';
export default {
name: "responderBatch",
props: {
selected: {
type: Object,
default: function() {
return null;
}
},
field: {
type: String,
default: ""
},
responderTypeList: {
type: Array,
required: true
},
sectionList: {
type: Array,
required: true
},
signalList: {
type: Array,
required: true
},
responderList: {
type: Array,
required: true
}
},
data() {
return {
formData: {
sectionCode: "",
type: "",
count: 0
},
subFormData: [],
row: -2,
formRules: {
sectionCode: [
{
required: true,
message: "请选择区段"
}
],
type: [
{
required: true,
message: "请选择类型"
}
],
count: [
{
validator: (rule, value, cb) => {
value !== 0 ? cb() : cb(new Error("至少创建一个"));
}
}
]
}
};
},
methods: {
setModelProp(selected, prop) {
if (prop === "sectionCode") {
//
this.formData[prop] = selected.code;
} else if (prop === "signalCode") {
//
this.subFormData[this.row][prop] = selected.code;
}
},
numBlur() {
const oldNum = this.subFormData.length;
const newNum = this.formData.count;
if (oldNum < newNum) {
this.subFormData = [
...this.subFormData,
...this.createSubForm(newNum - oldNum)
];
} else if (oldNum > newNum) {
this.subFormData = this.subFormData.slice(0, newNum);
}
},
createSubForm(length) {
return Array.from({ length }, _ => {
return {
name: "",
type: this.formData.type,
offset: 0,
signalCode: ""
};
});
},
changeSubFormType() {
this.subFormData.forEach(_ => {
_.type = this.formData.type;
});
},
handleHover(row, prop) {
this.row = row;
this.$emit("hover", prop);
},
doBatchCreate() {
this.$refs.form.validate(valid => {
if (valid) {
const groupMap = {};
const models = [];
//
this.subFormData.forEach(el => {
if (el.type !== "VB") el.signalCode = "";
el.sectionCode = this.formData.sectionCode;
if (!groupMap[el.sectionCode]) {
groupMap[el.sectionCode] = [];
}
groupMap[el.sectionCode].push(el);
});
name: 'ResponderBatch',
props: {
selected: {
type: Object,
default: function() {
return null;
}
},
field: {
type: String,
default: ''
},
responderTypeList: {
type: Array,
required: true
},
sectionList: {
type: Array,
required: true
},
signalList: {
type: Array,
required: true
},
responderList: {
type: Array,
required: true
}
},
data() {
return {
formData: {
sectionCode: '',
type: '',
count: 0
},
subFormData: [],
row: -2,
formRules: {
sectionCode: [
{
required: true,
message: '请选择区段'
}
],
type: [
{
required: true,
message: '请选择类型'
}
],
count: [
{
validator: (rule, value, cb) => {
value !== 0 ? cb() : cb(new Error('至少创建一个'));
}
}
]
}
};
},
methods: {
setModelProp(selected, prop) {
if (prop === 'sectionCode') {
//
this.formData[prop] = selected.code;
} else if (prop === 'signalCode') {
//
this.subFormData[this.row][prop] = selected.code;
}
},
numBlur() {
const oldNum = this.subFormData.length;
const newNum = this.formData.count;
if (oldNum < newNum) {
this.subFormData = [
...this.subFormData,
...this.createSubForm(newNum - oldNum)
];
} else if (oldNum > newNum) {
this.subFormData = this.subFormData.slice(0, newNum);
}
},
createSubForm(length) {
return Array.from({ length }, _ => {
return {
name: '',
type: this.formData.type,
offset: 0,
signalCode: ''
};
});
},
changeSubFormType() {
this.subFormData.forEach(_ => {
_.type = this.formData.type;
});
},
handleHover(row, prop) {
this.row = row;
this.$emit('hover', prop);
},
doBatchCreate() {
this.$refs.form.validate(valid => {
if (valid) {
const groupMap = {};
const models = [];
//
this.subFormData.forEach(el => {
if (el.type !== 'VB') el.signalCode = '';
el.sectionCode = this.formData.sectionCode;
if (!groupMap[el.sectionCode]) {
groupMap[el.sectionCode] = [];
}
groupMap[el.sectionCode].push(el);
});
//
Object.keys(groupMap).forEach(code => {
const section = this.$store.getters[
"map/getDeviceByCode"
](code);
const list = groupMap[code];
const length = list.length;
const ox =
//
Object.keys(groupMap).forEach(code => {
const section = this.$store.getters[
'map/getDeviceByCode'
](code);
const list = groupMap[code];
const length = list.length;
const ox =
(section.points[section.points.length - 1].x -
section.points[0].x) /
(length + 1);
const oy =
const oy =
(section.points[section.points.length - 1].y -
section.points[0].y) /
(length + 1);
list.forEach((el, i) => {
const x = section.points[0].x + ox * (i + 1);
const y = section.points[0].y + oy * (i + 1);
models.push(
utils.buildModelBySection(
section,
{ x, y },
el,
this.responderList
)
);
});
});
//
this.$emit("updateMapModel", models);
}
});
},
resetForm() {
this.formData = {
sectionCode: "",
type: "",
count: 0
};
this.numBlur();
}
}
list.forEach((el, i) => {
const x = section.points[0].x + ox * (i + 1);
const y = section.points[0].y + oy * (i + 1);
models.push(
utils.buildModelBySection(
section,
{ x, y },
el,
this.responderList
)
);
});
});
//
this.$emit('updateMapModel', models);
}
});
},
resetForm() {
this.formData = {
sectionCode: '',
type: '',
count: 0
};
this.numBlur();
}
}
};
</script>

View File

@ -1,72 +1,74 @@
<template>
<div class="content">
<el-button type="primary" size="mini" @click="batchConnectHandler"
>一键关联信号机</el-button
>
<div class="desc">一键将未关联信号机的可变应答器关联到最近的信号机</div>
</div>
<div class="content">
<el-button
type="primary"
size="mini"
@click="batchConnectHandler"
>一键关联信号机</el-button>
<div class="desc">一键将未关联信号机的可变应答器关联到最近的信号机</div>
</div>
</template>
<script>
export default {
name: "responderBatchOperate",
props: ["responderList", "signalList"],
data() {
return {};
},
methods: {
batchConnectHandler() {
try {
let models = this.responderList.filter(
el => el.type === "VB" && !el.signalCode
);
models.forEach(responder => {
const sectionCode = responder.sectionCode;
let signals = this.signalList.filter(
signal => signal.sectionCode === sectionCode
);
if (signals.length === 1) {
responder.signalCode = signals[0].code;
} else if (signals.length > 1) {
let signalsPosition = signals.map(_ => _.position);
let nearestSignalCode =
name: 'ResponderBatchOperate',
props: ['responderList', 'signalList'],
data() {
return {};
},
methods: {
batchConnectHandler() {
try {
const models = this.responderList.filter(
el => el.type === 'VB' && !el.signalCode
);
models.forEach(responder => {
const sectionCode = responder.sectionCode;
const signals = this.signalList.filter(
signal => signal.sectionCode === sectionCode
);
if (signals.length === 1) {
responder.signalCode = signals[0].code;
} else if (signals.length > 1) {
const signalsPosition = signals.map(_ => _.position);
const nearestSignalCode =
signals[
this.chooseNearestSignal(
responder.position,
signalsPosition
)
this.chooseNearestSignal(
responder.position,
signalsPosition
)
].code;
responder.signalCode = nearestSignalCode;
}
});
this.$emit("updateMapModel", models);
this.$message.success("关联成功");
} catch (error) {
this.$message.info(error);
}
},
responder.signalCode = nearestSignalCode;
}
});
this.$emit('updateMapModel', models);
this.$message.success('关联成功');
} catch (error) {
this.$message.info(error);
}
},
/**
/**
* 计算最近的信号机的序号
* @param {Object} respPos
* @param {Number} respPos.x
* @param {Number} respPos.y
* @returns {Number} index of the Nearest element
*/
chooseNearestSignal(respPos, sigPos) {
let [minDistance, idx] = [Infinity, -1];
sigPos.forEach((s, i) => {
let distance = this.distanceOf(respPos, s);
if (distance < minDistance) [minDistance, idx] = [distance, i];
});
return idx;
},
chooseNearestSignal(respPos, sigPos) {
let [minDistance, idx] = [Infinity, -1];
sigPos.forEach((s, i) => {
const distance = this.distanceOf(respPos, s);
if (distance < minDistance) [minDistance, idx] = [distance, i];
});
return idx;
},
//
distanceOf(a, b) {
return Math.hypot(b.x - a.x, b.y - a.y);
}
}
//
distanceOf(a, b) {
return Math.hypot(b.x - a.x, b.y - a.y);
}
}
};
</script>

View File

@ -34,11 +34,11 @@ export default {
sectionList: {
type: Array,
required: true
},
signalList: {
},
signalList: {
type: Array,
required: true
},
},
responderList: {
type: Array,
required: true
@ -49,8 +49,8 @@ export default {
addModel: {
type: '',
name: '',
sectionCode: '',
signalCode: ''
sectionCode: '',
signalCode: ''
},
rules: {
name: [
@ -61,20 +61,20 @@ export default {
],
sectionCode: [
{ required: true, message: '请关联物理区段', trigger: 'blur' }
],
signalCode: [
],
signalCode: [
{ required: true, message: '请关联信号机', trigger: 'blur' }
]
]
}
};
},
computed: {
isSectionButtonType() {
return this.field == 'RelSectionCode';
},
isSignalButtonType() {
},
isSignalButtonType() {
return this.field == 'RelSignalCode';
},
},
createForm() {
const form = {
labelWidth: '110px',
@ -84,8 +84,8 @@ export default {
item: [
{ prop: 'name', label: '应答器名称', type: 'input' },
{ prop: 'type', label: `应答器类型`, type: 'select', optionLabel: 'name&&value', optionValue: 'value', options: this.responderTypeList },
{ prop: 'sectionCode', label: '关联区段', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.sectionList, buttonType: 'RelSectionCode', hover: this.hover, buttonShowType: this.isSectionButtonType },
{ prop: 'signalCode', label: '关联信号机', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.signalList, buttonType: 'RelSignalCode', hover: this.hover, buttonShowType: this.isSignalButtonType },
{ prop: 'sectionCode', label: '关联区段', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.sectionList, buttonType: 'RelSectionCode', hover: this.hover, buttonShowType: this.isSectionButtonType },
{ prop: 'signalCode', label: '关联信号机', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.signalList, buttonType: 'RelSignalCode', hover: this.hover, buttonShowType: this.isSignalButtonType }
]
}
}
@ -101,10 +101,10 @@ export default {
this.addModel[prop] = selected.code;
},
create() {
const section = this.$store.getters['map/getDeviceByCode'](this.addModel.sectionCode);
const length = section.points.length;
const x = (section.points[length - 1].x + section.points[0].x) / 2;
const y = (section.points[length - 1].y + section.points[0].y) / 2;
const section = this.$store.getters['map/getDeviceByCode'](this.addModel.sectionCode);
const length = section.points.length;
const x = (section.points[length - 1].x + section.points[0].x) / 2;
const y = (section.points[length - 1].y + section.points[0].y) / 2;
const model = utils.buildModelBySection(section, {x, y}, this.addModel, this.responderList);
this.$refs.createForm.resetForm();
this.$emit('updateMapModel', model);

View File

@ -37,11 +37,11 @@ export default {
sectionList: {
type: Array,
required: true
},
signalList: {
type: Array,
required: true
},
},
signalList: {
type: Array,
required: true
},
responderList: {
type: Array,
required: true
@ -69,8 +69,8 @@ export default {
},
offset: 0,
sectionCode: '',
stationCode: '',
signalCode: ''
stationCode: '',
signalCode: ''
},
rules: {
code: [
@ -93,10 +93,10 @@ export default {
],
sectionCode: [
{ required: true, message: '请关联物理区段', trigger: 'blur' }
],
signalCode: [
],
signalCode: [
{ required: true, message: '请关联信号机', trigger: 'blur' }
],
],
'position.x': [
{ required: true, message: '请输入应答器坐标x', trigger: 'blur' }
],
@ -113,10 +113,10 @@ export default {
};
},
computed: {
isSectionButtonType() {
isSectionButtonType() {
return this.field == 'RelModelSectionCode';
},
isSignalButtonType() {
},
isSignalButtonType() {
return this.field == 'RelModelSignalCode';
},
form() {
@ -144,9 +144,9 @@ export default {
{ prop: 'textOffset.y', firstLevel: 'textOffset', secondLevel: 'y', label: 'y:', type: 'number', labelWidth: '25px', disabled: false }
] },
{ prop:'textRotate', label: '文字旋转', type: 'number' },
{ prop: 'sectionCode', label: '关联区段', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.sectionList, buttonType: 'RelModelSectionCode', hover: this.hover, buttonShowType: this.isSectionButtonType },
this.editModel.type === 'VB'? { prop: 'signalCode', label: '关联信号机', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.signalList, buttonType: 'RelModelSignalCode', hover: this.hover, buttonShowType: this.isSignalButtonType } :'',
{ prop: 'stationCode', label: '关联集中站' + ':', type: 'select', optionLabel: 'name&&code', optionValue: 'code', options: this.centralizedStationList }
{ prop: 'sectionCode', label: '关联区段', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.sectionList, buttonType: 'RelModelSectionCode', hover: this.hover, buttonShowType: this.isSectionButtonType },
this.editModel.type === 'VB' || this.editModel.type === 'IB' ? { prop: 'signalCode', label: '关联信号机', type: 'selectHover', optionLabel: 'name&&code', optionValue: 'code', options: this.signalList, buttonType: 'RelModelSignalCode', hover: this.hover, buttonShowType: this.isSignalButtonType } : '',
{ prop: 'stationCode', label: '关联集中站' + ':', type: 'select', optionLabel: 'name&&code', optionValue: 'code', options: this.centralizedStationList }
]
},
map: {
@ -160,14 +160,14 @@ export default {
}
},
methods: {
hover(field) {
hover(field) {
this.$emit('hover', field);
},
setModelProp(selected, prop) {
this.editModel[prop] = selected.code;
},
},
setModelProp(selected, prop) {
this.editModel[prop] = selected.code;
},
setModel(selected) {
if (!selected.signalCode) selected.signalCode = '';
if (!selected.signalCode) selected.signalCode = '';
this.editModel = deepAssign(this.editModel, selected);
},
deviceChange(code) {
@ -183,6 +183,9 @@ export default {
this.$refs.dataform.edit();
},
updateMapModel(data) {
if (data.type !== 'VB' && data.type !== 'IB') {
data.signalCode = '';
}
this.$emit('updateMapModel', data);
}
}

BIN
static/jl3d/tms/PMS3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/jl3d/tms/PMsa2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB