运行图加载调整&交路数据调整

This commit is contained in:
fan 2020-04-21 15:08:27 +08:00
parent 7c55c19933
commit 2f4b765d97
21 changed files with 2433 additions and 323 deletions

View File

@ -605,3 +605,10 @@ export function exitRunPlan (group) {
method: 'post'
});
}
/** 加载指定运行计划 */
export function simulationLoadRunPlan(group, templateId) {
return request({
url: `/simulation/${group}/load/runPlan/${templateId}`,
method: 'put'
});
}

View File

@ -143,7 +143,7 @@
</el-row>
</template>
</el-col>
<el-col :span="24-leftSpan-1" :offset="1">
<el-col :span="24-leftSpan-1" :offset="offsetSpan">
<el-button style="margin-right: 10px" type="primary" size="small" :disabled="!canQuery" @click="query">{{ $t('global.query') }}</el-button>
<el-button v-if="queryForm.reset" type="primary" size="small" :disabled="!canQuery" @click="doClean">{{ $t('global.reset') }}</el-button>
<el-button v-if="exportFlag" type="primary" size="small" :disabled="!canQuery" @click="doExport">{{ $t('global.export') }}</el-button>
@ -201,6 +201,12 @@ export default {
default() {
return 18;
}
},
offsetSpan: {
type: Number,
default() {
return 1;
}
}
},
data() {

View File

@ -6,6 +6,7 @@
ref="queryForm"
:query-form="queryForm"
:left-span="queryForm.leftSpan"
:offset-span="queryForm.offsetSpan"
:query-list="queryList"
:before-query="queryForm.beforeQuery"
:can-query="canQuery"
@ -32,7 +33,7 @@
>
<el-table-column v-if="queryList.selectCheckShow" type="selection" width="55" />
<el-table-column v-if="queryList.indexShow" type="index" width="50" :label="this.$t('global.index')" />
<el-table-column v-if="queryList.radioShow" :label="`#${$t('global.select')}`" width="60">
<el-table-column v-if="queryList.radioShow" :label="`#${$t('global.select')}`" width="80">
<template slot-scope="scope">
<el-radio v-model="choose" :label="scope.row">{{ `` }}</el-radio>
</template>

View File

@ -139,5 +139,5 @@ export default {
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
/*@import "src/styles/mixin.scss";*/
</style>

View File

@ -138,75 +138,34 @@ export default {
tempClassB: -1,
menu: [
{
title: '文件F',
children: [
]
},
{
title: '显示V',
children: [
// {
// title: '',
// },
// {
// title: '',
// },
// {
// title: ''
// }
]
},
{
title: '编辑E',
children: [
// {
// title: '',
// click: this.handleEditPlanningTrain
// },
// {
// title: '',
// click: this.handleAddTask
// },
// {
// title: '',
// click: this.handleDeleteTask
// },
// {
// title: '',
// click: this.handleModifyingPlanId
// },
// {
// title: '',
// click: this.handleTranslationalMulTrain
// }
]
},
{
title: '工具T',
children: [
{
title: '查看计划列表',
title: '管理运行计划',
click: this.handleViewPlanSchedule
},
{
title: '创建一周计划',
click: this.handleCreateWeekPlan
},
{
title: '加载当天计划',
title: '加载今日计划',
click: this.handleReloadTodayPlan
}
// {
// title: '',
// click: this.handleValidityCheck
// title: 'T',
// children: [
// {
// title: '',
// click: this.handleViewPlanSchedule
// },
// {
// title: '',
// click: this.handleCreateWeekPlan
// },
// {
// title: '',
// click: this.handleReloadTodayPlan
// }
// // {
// // title: '',
// // click: this.handleValidityCheck
// // }
// ]
// }
]
},
{
title: '帮助H',
children: [
]
}
]
};
},

View File

@ -1,4 +1,31 @@
import { createMartPoint, createSeriesModel, createMarkLineModels, hexColor, convertSheetToList, prefixTime } from '@/utils/runPlan';
import { createMartPoint, createSeriesModel, createMarkLineModels, hexColor, convertSheetToList } from '@/utils/runPlan';
const StationMap = {
YARD1: '潏河转换轨',
YARD2: '潏河转换轨',
WQN: '韦曲南站',
HTC: '航天城站',
FQY: '凤栖原站',
SYZ: '三爻站',
HZX: '会展中心站',
WYJ: '纬一街站',
XZZ: '小寨站',
TYC: '体育场站',
NSM: '南稍门站',
YNM: '永宁门站',
ZLZ: '钟楼站',
BDJ: '北大街站',
AYM: '安远门站',
LSY: '龙首原站',
DMG: '大明宫西站',
STS: '市图书馆站',
FCW: '凤城五路站',
XZX: '行政中心站',
YDG: '运动公园站',
BYZ: '北苑站',
BKZ: '北客站',
NDOP1: '渭河转换轨',
NDOP2: '渭河转换轨'
};
export default {
/** 边缘高度*/
@ -9,119 +36,113 @@ export default {
/** 偏移时间*/
TranslationTime: 60 * 60 * 2,
/** excel解析配置*/
ExcelConfig: {
beginRow: 1,
beginCol: 0,
fieldNum: 10,
sepField: '行车间隔',
trainId: 'TrainID',
columns: ['折返线', 'TrainID', '行车间隔']
fieldNum: 8,
sepField: 'Trip',
idField: 'Train ID',
columns: {
'LOC': { key: 'stationName', formatter: (val) => { return StationMap[val]; } },
'Arrive': { key: 'arriveTime', formatter: (val) => { return val; } },
'Depart': { key: 'departureTime', formatter: (val) => { return val; } }
}
},
/** 解析exal数据转换为Json后台数据*/
importData(Sheet, JsonData) {
var dataList = convertSheetToList(Sheet, true);
var needList = Object.keys(this.ExcelConfig.columns);
if (dataList && dataList.length) {
if (dataList && dataList.length && dataList[1] && dataList[0]) {
// const tIndex = dataList.findIndex(it => { return it[0]; }); // 设置不用过滤行数
const tIndex = 9; // 设置不用过滤行数
for (var colIndex = this.ExcelConfig.beginCol; colIndex < dataList.length; colIndex += this.ExcelConfig.fieldNum + 1) {
var isContinue = true;
var tripObj = { code: '', trainId: '', arrivalList: [] };
/** 解析二维数组为json对象*/
const reg3 = /^(\d+:\d+:\d+|)/; // 06:12:00
dataList.forEach((elem, i) => {
var begin = -1;
/** 跳过名称所在的行*/
if (i != tIndex && elem && elem.length > 0) {
let flag = false;
let count = 0;
let param = { begTime: '', endTime: '' };
if (i > tIndex) { elem.reverse(); }
elem.forEach((item, j) => {
/** 过滤空值*/
if (item) {
let title = '';
var value = `${item}`.trim();
if (i > tIndex) { // 上行线
title = `${dataList[tIndex][dataList[tIndex].length - j - 1]}`.replace(/\s*/g, '');
if (title == 'undefined') {
title = `${dataList[tIndex][dataList[tIndex].length - j - 2]}`.replace(/\s*/g, '');
for (var rowIndex = this.ExcelConfig.beginRow; isContinue; rowIndex += 1) {
isContinue = false;
var stationObj = {};
for (var index = 0; index < this.ExcelConfig.fieldNum; index += 1) {
if (dataList[colIndex + index]) {
var title = dataList[colIndex + index][0];
var value = dataList[colIndex + index][rowIndex];
if (title && value) {
// 数据列解析
isContinue = true;
var titleStr = `${title}`.trim();
var valueStr = `${value}`.trim();
if (titleStr == this.ExcelConfig.sepField) {
if (tripObj.code) {
const length = tripObj.arrivalList.length;
if (length == 1) {
tripObj.arrivalList[0]['flag'] = true;
}
if (valueStr.includes('FT') || valueStr.includes('LT')) {
valueStr = valueStr.replace('FT', '').replace('LT', '');
console.log(valueStr);
}
valueStr = tripObj.trainId + valueStr;
delete tripObj.trainId;
JsonData.push(tripObj);
tripObj = { code: valueStr, arrivalList: [] };
} else {
if (valueStr.includes('FT') || valueStr.includes('LT')) {
valueStr = valueStr.replace('FT', '').replace('LT', '');
}
valueStr = tripObj.trainId + valueStr;
delete tripObj.trainId;
tripObj.code = valueStr;
}
} else if (titleStr === this.ExcelConfig.idField) {
tripObj.trainId = valueStr;
}
// 取需要的字段
if (needList.findIndex(elem => { return elem == titleStr; }) >= 0) {
stationObj[this.ExcelConfig.columns[titleStr].key] = this.ExcelConfig.columns[titleStr].formatter(valueStr);
}
}
} else { // 下行线
title = `${dataList[tIndex][j]}`.replace(/\s*/g, '');
if (title == 'undefined') {
title = `${dataList[tIndex][j - 1]}`.replace(/\s*/g, '');
}
}
/** 匹配到开始位置或者结束位置*/
if (title == this.ExcelConfig.trainId) {
if (begin == -1) {
flag = true;
begin = value; // 设置初始索引
JsonData.push({
code: value,
destinationCode: '',
arrivalList: []
});
} else if (flag) {
begin = -1; // 清空初始索引
JsonData[JsonData.length - 1].destinationCode = value;
flag = false;
// 添加字段值
if (Object.keys(stationObj).length) {
if (!stationObj.departureTime) {
stationObj.departureTime = stationObj.arriveTime;
} else if (!stationObj.arriveTime) {
stationObj.arriveTime = stationObj.departureTime;
}
} else if (begin !== -1) {
/** 匹配到中间位置*/
var stationName = title.replace(/\s/, '');
if (this.ExcelConfig.columns.indexOf(stationName) == -1 && reg3.test(value)) {
let need = false;
if (value.split(':')[0] == '24') { // 24:XX:XX 类似这种数据 变24为00
const arr = value.split(':');
arr[0] = '00';
value = arr.join(':');
tripObj.arrivalList.push(stationObj);
}
if (count == 1) {
count = 0;
param.endTime = value;
}
if (count == 0) {
count = 1;
param.begTime = param.begTime || value;
}
if (param.begTime && param.endTime) {
need = true;
// 添加最后那条没有车次的记录
if (tripObj.code) {
const length = tripObj.arrivalList.length;
if (length) {
tripObj.arrivalList[length - 1]['flag'] = true;
}
/** 添加json数据*/
if (need) { // 储存非空 数据
var stationObj = {
stationName: stationName
};
stationObj['arriveTime'] = prefixTime(param.begTime);
stationObj['departureTime'] = prefixTime(param.endTime);
JsonData[JsonData.length - 1].arrivalList.push(stationObj);
param = { begTime: '', endTime: '' };
count = 0;
JsonData.push(tripObj);
}
}
}
}
});
}
});
}
}
return JsonData;
},
/** 将后台数据解析成图表*/
convertDataToModels(data, stations, kmRangeCoordMap, lineStyle) {
var models = [];
if (data && data.serviceNumberDataList && data.serviceNumberDataList.length) {
/** 按服务遍历数据*/
data.serviceNumberDataList.forEach((service) => {
/** 按车次遍历数据*/
var isBackup = true;
var opt = { name: '', markPointData: [], data: [] };
if (service.tripNumberDataList && service.tripNumberDataList.length) {
service.tripNumberDataList.forEach((train, j) => {
@ -161,8 +182,9 @@ export default {
lastPoint = train.stationTimeList[idx - 1];
nextPoint = service.tripNumberDataList[j + 1].stationTimeList[1];
num = this.computedReentryNumber(train.tripNumber);
opt.data.push([lastPoint.secondTime, this.getCoordYByElem(stations, kmRangeCoordMap, lastPoint, train.directionCode, true, num), lastPoint.stationCode]);
opt.data.push([nextPoint.secondTime, this.getCoordYByElem(stations, kmRangeCoordMap, nextPoint, train.directionCode, true, num), nextPoint.stationCode]);
const aa = `${train.directionCode}${train.tripNumber}`;
opt.data.push([lastPoint.secondTime, this.getCoordYByElem(stations, kmRangeCoordMap, lastPoint, train.directionCode, true, num), lastPoint.stationCode, aa]);
opt.data.push([nextPoint.secondTime, this.getCoordYByElem(stations, kmRangeCoordMap, nextPoint, train.directionCode, true, num), nextPoint.stationCode, aa]);
}
/** 如果是备用车,按车次添加线*/
@ -175,10 +197,12 @@ export default {
opt = { name: '', markPointData: [], data: [] };
}
}
isBackup = train.backup;
});
// 不是备用车,按服务添加线
if (!service.backup) {
if (!isBackup) {
/** 创建一条完成的服务数据*/
var model = createSeriesModel(opt, Object.assign({ color: hexColor.toCreate() }, lineStyle));
if (model) {
@ -201,6 +225,7 @@ export default {
if (!runPlanData[elem.serviceNumber]) {
/** 创建一个新服务号标记*/
runPlanData[elem.serviceNumber] = {};
/** 不存在此服务号则需要创建一条新的line*/
series.push(createSeriesModel({
zlevel: 1,

View File

@ -81,6 +81,9 @@ function handle(state, data) {
case 'Be_Logged_Out': // 重复登录被登出
state.beLogoutCount++;
break;
case 'Simulation_Run_Plan_Reload': // 运行图变更
state.runPlanReloadCount++;
break;
case 'Simulation_Control_Pause': // 暂停中
store.dispatch('scriptRecord/updateSimulationPause', msg);
break;
@ -233,7 +236,8 @@ const socket = {
tipOperateCount: 0, // 任务结束提示消息
realDeviceInfo: 0, // 真实设备信息
beLogoutCount: 0 // 被登出
beLogoutCount: 0, // 被登出
runPlanReloadCount: 0 // 仿真运行图变更
},
getters: {

View File

@ -2,11 +2,11 @@ export function getBaseUrl() {
let BASE_API;
if (process.env.NODE_ENV === 'development') {
// BASE_API = 'https://joylink.club/jlcloud';
BASE_API = 'https://test.joylink.club/jlcloud';
// BASE_API = 'https://test.joylink.club/jlcloud';
// BASE_API = 'http://192.168.3.5:9000'; // 袁琪
// BASE_API = 'http://192.168.3.6:9000'; // 旭强
// BASE_API = 'http://192.168.3.41:9000'; // 张赛
// BASE_API = 'http://192.168.3.82:9000'; // 杜康
BASE_API = 'http://192.168.3.82:9000'; // 杜康
// BASE_API = 'http://192.168.3.41:9000'; // 张赛
// BASE_API = 'http://b29z135112.zicp.vip';
// BASE_API = 'http://2925963m2a.zicp.vip'; // 杜康

View File

@ -1,14 +1,18 @@
<template>
<div v-show="show" class="run-plan-dialog">
<component :is="menus" ref="schedule" :group="group" @back="doClose" />
<plan-schedule ref="planSchedule" :group="group" @back="doClose" />
</div>
</template>
<script>
import PlanSchedule from '@/views/planSchedule/index';
import { getEveryDayRunPlanNew } from '@/api/simulation';
//
export default {
name: 'RunPlanLoad',
components: {
PlanSchedule
},
props: {
group: {
type: String,
@ -29,17 +33,19 @@ export default {
watch: {
'$route.query.lineCode': function (code) {
if (code) {
this.menus = this.$theme.loadPlanComponent(code);
// this.menus = this.$theme.loadPlanComponent(code);
}
},
'$store.state.socket.runPlanReloadCount': function (val) {
}
},
mounted() {
this.menus = this.$theme.loadPlanComponent(this.$route.query.lineCode);
// this.menus = this.$theme.loadPlanComponent(this.$route.query.lineCode);
},
methods: {
doShow() {
this.show = true;
this.$refs.schedule.setPosition();
this.$refs.planSchedule.setPosition();
},
doClose() {
this.show = false;

View File

@ -101,11 +101,14 @@ export default {
prop: 'description'
},
{
type: 'button',
title: this.$t('map.sectionData'),
prop: 'parkSectionCodeList',
type: 'tagMore',
columnValue: (row) => { return this.handlerParkSectionCodeList(row.parkSectionCodeList); },
tagType: 'primary'
buttons: [
{
name: this.$t('map.preview'),
handleClick: this.sectionDetail
}
]
},
{
type: 'button',
@ -156,15 +159,15 @@ export default {
doClose() {
this.show = false;
},
handlerParkSectionCodeList(parkSectionCodeList) {
const nameList = [];
this.sectionList.forEach(item => {
if (parkSectionCodeList.includes(item.code)) {
nameList.push(item.name);
}
});
return nameList;
},
// handlerParkSectionCodeList(parkSectionCodeList) {
// const nameList = [];
// this.sectionList.forEach(item => {
// if (parkSectionCodeList.includes(item.code)) {
// nameList.push(item.name);
// }
// });
// return nameList;
// },
formatName(code) {
let name = '';
const device = this.$store.getters['map/getDeviceByCode'](code);
@ -229,7 +232,7 @@ export default {
const fieldList = {
id: row.id,
mapId: this.$route.params.mapId,
title: '',
title: '区段列表',
name: row.name,
model: {
field: 'parkSectionCodeList',

View File

@ -78,34 +78,8 @@
<el-form-item :label="$t('map.remarksColon')" prop="description">
<el-input v-model="addModel.description" type="textarea" :rows="4" :placeholder="$t('map.pleaseSelect')" />
</el-form-item>
<el-form-item :label="$t('map.trafficSegmentData')" prop="parkSectionCodeList">
<el-select v-model="addModel.parkSectionCodeList" multiple>
<el-option
v-for="item in sectionList"
:key="item.code"
:label="`${item.name}(${item.code})`"
:value="item.code"
/>
</el-select>
<el-button :type=" field === 'routingSection' ? 'danger' : 'primary'" @click="hover('routingSection')">{{ $t('map.activate') }}</el-button>
</el-form-item>
<!--<el-form-item :label="$t('map.trafficSegmentData')" prop="routingSectionList">-->
<!--<div>-->
<!--<el-select v-model="stationCode" clearable :filterable="true" :placeholder="$t('map.pleaseSelect')">-->
<!--<el-option-->
<!--v-for="item in filterStationList"-->
<!--:key="item.code"-->
<!--:label="`${item.name}(${item.code})`"-->
<!--:value="item.code"-->
<!--/>-->
<!--</el-select>-->
<!--<el-button-->
<!--:type="field === 'routingStation' ? 'danger' : 'primary'"-->
<!--@click="hover('routingStation')"-->
<!--&gt;{{ $t('map.activate') }}</el-button>-->
<!--</div>-->
<!--<div>-->
<!--<el-select v-model="sectionCode" clearable :filterable="true" :placeholder="$t('map.pleaseSelect')">-->
<!--<el-form-item :label="$t('map.trafficSegmentData')" prop="parkSectionCodeList">-->
<!--<el-select v-model="addModel.parkSectionCodeList" multiple>-->
<!--<el-option-->
<!--v-for="item in sectionList"-->
<!--:key="item.code"-->
@ -113,41 +87,69 @@
<!--:value="item.code"-->
<!--/>-->
<!--</el-select>-->
<!--<el-button-->
<!--:type=" field === 'routingSection' ? 'danger' : 'primary'"-->
<!--@click="hover('routingSection')"-->
<!--&gt;{{ $t('map.activate') }}</el-button>-->
<!--<el-button-->
<!--type="primary"-->
<!--@click="pushSection(addModel.routingSectionList, {stationCode: stationCode, sectionCode: sectionCode})"-->
<!--&gt;-->
<!--{{ $t('map.add') }}-->
<!--</el-button>-->
<!--</div>-->
<!--<el-table :data="addModel.routingSectionList" border style="width: 97%">-->
<!--<el-table-column prop="sectionCode" :label="$t('map.stationName')">-->
<!--<template slot-scope="scope">-->
<!--<span>{{ formatName(scope.row.stationCode) }}</span>-->
<!--</template>-->
<!--</el-table-column>-->
<!--<el-table-column prop="sectionCode" :label="$t('map.sectionName')">-->
<!--<template slot-scope="scope">-->
<!--<span>{{ formatName(scope.row.sectionCode) }}</span>-->
<!--</template>-->
<!--</el-table-column>-->
<!--<el-table-column fixed="right" :label="$t('map.operation')" width="50">-->
<!--<template slot-scope="scope">-->
<!--<el-button-->
<!--type="text"-->
<!--size="small"-->
<!--@click.native.prevent="deleteSection(addModel.routingSectionList, scope.$index)"-->
<!--&gt;-->
<!--{{ $t('map.remove') }}-->
<!--</el-button>-->
<!--</template>-->
<!--</el-table-column>-->
<!--</el-table>-->
<!--<el-button :type=" field === 'routingSection' ? 'danger' : 'primary'" @click="hover('routingSection')">{{ $t('map.activate') }}</el-button>-->
<!--</el-form-item>-->
<el-form-item :label="$t('map.trafficSegmentData')" prop="parkSectionCodeList">
<div>
<span>车站:</span>
<el-select v-model="stationCode" clearable :filterable="true" :placeholder="$t('map.pleaseSelect')">
<el-option
v-for="item in filterStationList"
:key="item.code"
:label="`${item.name}(${item.code})`"
:value="item.code"
/>
</el-select>
<el-button
:type="field === 'routingStation' ? 'danger' : 'primary'"
@click="hover('routingStation')"
>{{ $t('map.activate') }}</el-button>
</div>
<div>
<span>区段:</span>
<el-select v-model="sectionCode" clearable :filterable="true" :placeholder="$t('map.pleaseSelect')">
<el-option
v-for="item in sectionList"
:key="item.code"
:label="`${item.name}(${item.code})`"
:value="item.code"
/>
</el-select>
<el-button
:type=" field === 'routingSection' ? 'danger' : 'primary'"
@click="hover('routingSection')"
>{{ $t('map.activate') }}</el-button>
<el-button
type="primary"
@click="pushSection(addModel.parkSectionCodeList, {stationCode: stationCode, sectionCode: sectionCode})"
>
{{ $t('map.add') }}
</el-button>
</div>
<el-table :data="addModel.parkSectionCodeList" border style="width: 97%">
<el-table-column prop="sectionCode" :label="$t('map.stationName')">
<template slot-scope="scope">
<span>{{ formatName(scope.row.stationCode) }}</span>
</template>
</el-table-column>
<el-table-column prop="sectionCode" :label="$t('map.sectionName')">
<template slot-scope="scope">
<span>{{ formatName(scope.row.sectionCode) }}</span>
</template>
</el-table-column>
<el-table-column fixed="right" :label="$t('map.operation')" width="50">
<template slot-scope="scope">
<el-button
type="text"
size="small"
@click.native.prevent="deleteSection(addModel.parkSectionCodeList, scope.$index)"
>
{{ $t('map.remove') }}
</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item>
<el-button-group>
<el-button v-if="isSave" type="primary" size="small" :loading="loading" @click="save">{{ $t('map.save') }}
@ -254,9 +256,6 @@ export default {
} else {
return [];
}
},
newParkSectionCodeList() {
return JSON.stringify(this.addModel.parkSectionCodeList);
}
},
watch: {
@ -270,18 +269,6 @@ export default {
this.addModel = val;
this.editShow = true;
}
},
newParkSectionCodeList: {
handler: function(val, old) {
const obj = JSON.parse(val);
const objOld = JSON.parse(old);
if (objOld && objOld.length) {
this.changeSectionSelected(objOld);
}
if (obj && obj.length) {
this.changeSectionSelected(obj);
}
}
}
},
mounted() {
@ -319,7 +306,7 @@ export default {
this.addModel.endSectionCode = selected.code;
this.addModel.destinationCode = selected.destinationCode || '';
} else if (selected._type.toUpperCase() === 'Section'.toUpperCase() && this.field.toUpperCase() == 'routingSection'.toUpperCase()) {
this.addModel.parkSectionCodeList.push(selected.code);
this.sectionCode = selected.code;
} else if (selected._type.toUpperCase() === 'Station'.toUpperCase() && this.field.toUpperCase() == 'routingStation'.toUpperCase()) {
this.stationCode = selected.code;
}
@ -330,6 +317,8 @@ export default {
const index = list.findIndex(elem => { return elem.sectionCode == data.sectionCode; });
if (index < 0) {
list.push(data);
this.sectionCode = '';
this.stationCode = '';
} else {
this.$messageBox(this.$t('tip.routeSameID'));
}
@ -392,31 +381,6 @@ export default {
this.sectionCode = '';
this.isSave = true;
}
},
changeSectionSelected(list) {
let type = '';
let flag = true;
list && list.forEach((item) => {
const section = this.$store.getters['map/getDeviceByCode'](item);
if (this.addModel.parkSectionCodeList.includes(item)) {
type = 'routingSection';
flag = true;
} else {
type = '';
flag = false;
}
this.setSectionSelectedType(section, flag, type);
});
},
setSectionSelectedType(section, flag, type) {
if (section && section.logicSectionCodeList && section.logicSectionCodeList.length) {
section.logicSectionCodeList.forEach( (logicSectionCode) => {
const logicSection = this.$store.getters['map/getDeviceByCode'](logicSectionCode);
logicSection && logicSection.instance.drawBatchSelected(flag, flag ? type : '');
});
} else {
section && section.instance.drawBatchSelected(flag, flag ? type : '');
}
}
}
};

View File

@ -0,0 +1,385 @@
<template>
<div class="plan-schedule" style="width: 100%">
<title-bar ref="titleBar" @back="back" />
<menu-bar ref="menuBar" :line-code="lineCode" @dispatchDialog="dispatchDialog" />
<schedule ref="schedule" :group="group" :line-code="lineCode" :max-height="height" :max-width="width" />
<status-bar ref="statusBar" :max-top="height" @setPosition="setPosition" />
<manage-plan-list ref="managePlanList" @dispatchDialog="dispatchDialog" />
<create-today-plan ref="createTodayPlan" />
</div>
</template>
<script>
import TitleBar from './titleBar';
import MenuBar from './menuBar';
import StatusBar from './statusBar';
import Schedule from './schedule';
import ManagePlanList from './menusPlan/managePlanList';
import CreateTodayPlan from './menusPlan/createTodayPlan';
export default {
name: 'Menus',
components: {
TitleBar,
MenuBar,
StatusBar,
Schedule,
ManagePlanList,
CreateTodayPlan
},
props: {
group: {
type: String,
required: true
}
},
data() {
return {
lineCode: ''
};
},
computed: {
skinCode() {
return this.$route.query.skinCode;
},
width() {
return this.$store.state.app.width;
},
height() {
return this.$store.state.app.height;
}
},
methods: {
setPosition() {
this.$nextTick(() => {
this.$refs.schedule.setPosition();
});
},
dispatchDialog(dialogObj) {
this.$nextTick(() => {
if (this.$refs[dialogObj.name]) {
this.$refs[dialogObj.name].doShow(dialogObj.params);
}
});
},
reloadTable(dialogObj) {
if (this.$refs[dialogObj.name]) {
this.$refs[dialogObj.name].reloadTable();
}
},
confirm(params) {
},
back() {
this.$emit('back');
}
}
};
</script>
<style>
.plan-schedule {
position: absolute;
background: gray;
}
.plan-schedule .pop-menu {
background: #F0F0F0;
}
.plan-schedule .pop-menu span {
color: #000;
}
.plan-schedule .system-close {
cursor: pointer;
position: absolute;
right: 0px;
background: -webkit-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -o-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -moz-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
border: 1px solid white;
border-radius: 4px;
}
.plan-schedule .system-close::before {
position: absolute;
height: 22px;
line-height: 22px;
top: 0px;
left: 0px;
font-size: x-large;
}
.plan-schedule .pop-menu .is-disabled span {
color: #B4B3B8;
}
.beijing-01__schedule {
overflow: hidden !important;
}
.plan-schedule-dialog .el-dialog {
background: #0099F8;
box-shadow: 1px hsla(240, 0%, 100%, 0.5) inset;
border: 2px solid #727375;
border-radius: 4px;
color: #000;
font-size: 14px;
}
.plan-schedule-dialog .el-dialog .el-dialog__header {
height: 30px;
padding: 5px;
background: -webkit-linear-gradient(#0055E8, #0099F8);
background: -o-linear-gradient(#0055E8, #0099F8);
background: -moz-linear-gradient(#0055E8, #0099F8);
background: linear-gradient(#0055E8, #0099F8);
}
.plan-schedule-dialog .el-dialog .el-dialog__footer {
background: #ECE9D8;
opacity: 1;
}
.plan-schedule-dialog .el-dialog .el-dialog__body {
padding-top: 10px;
padding-bottom: 10px;
padding-left: 5px;
padding-right: 5px;
margin: 0px 3px 3px 3px;
color: #000;
background: #FFFFFF;
opacity: 1;
}
.plan-schedule-dialog .el-dialog .el-dialog__title {
font-size: 16px;
color: #ffffff;
}
.plan-schedule-dialog .el-dialog .el-dialog__headerbtn {
background: -webkit-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -o-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: -moz-linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
background: linear-gradient(#CD98A0, #C27D6E, #B63022, #C68770);
border: 1px solid white;
border-radius: 4px;
top: 0px;
right: 3px;
line-height: 26px;
width: 26px;
}
.plan-schedule-dialog .el-dialog .el-dialog__headerbtn .el-icon-close:before {
font-size: 16px;
}
.plan-schedule-dialog .el-dialog .el-dialog__headerbtn .el-dialog__close {
color: #fff;
}
.beijing-01__schedule .el-dialog .el-form {
background: #ECE9D8 !important;
}
.beijing-01__schedule .el-dialog .el-card {
background: #ECE9D8 !important;
}
.plan-schedule-dialog .el-dialog .el-button .el-button--primary{
background: #0099F8;
}
.beijing-01__schedule .el-dialog .expand {
width: 120px;
}
/*.plan-schedule-dialog .el-dialog .el-button:focus span {*/
/*border: 1px dashed gray;*/
/*}*/
/*.plan-schedule-dialog .el-dialog .el-button:active {*/
/*border: 2px inset #E2E2E2;*/
/*}*/
/*.plan-schedule-dialog .el-dialog .el-button:disabled {*/
/*border: 2px inset #E2E2E2;*/
/*}*/
/*.plan-schedule-dialog .el-dialog .el-button:disabled span {*/
/*border: 0px;*/
/*}*/
.beijing-01__schedule .el-dialog .button-group {
margin: 0px 5px;
text-align: center !important;
}
.beijing-01__schedule .el-dialog .el-input {
border: 2px inset #E9E9E9;
}
.beijing-01__schedule .el-dialog .el-input .el-input__inner {
color: #000;
background: #fff !important;
border: 0px;
border-radius: 0px !important;
box-sizing: border-box;
}
.beijing-01__schedule .el-dialog .el-input.is-disabled .el-input__inner {
background: #F0F0F0 !important;
}
.beijing-01__schedule .el-dialog .el-textarea {
border: 2px inset #E9E9E9;
border-radius: 0px;
}
.beijing-01__schedule .el-dialog .el-textarea .el-textarea__inner {
color: #000;
background: #fff !important;
border: 0px;
border-radius: 0px !important;
box-sizing: border-box;
}
.beijing-01__schedule .el-dialog .el-textarea.is-disabled .el-textarea__inner {
background: #F0F0F0 !important;
}
.beijing-01__schedule .el-dialog .el-table {
border: 2px inset #E9E9E9;
color: #000 !important;
}
.plan-schedule-dialog .el-dialog .el-table .cell {
line-height: unset !important;
}
.beijing-01__schedule .el-dialog .el-table th.is-leaf {
background: #ECE9D8 !important;
border-right: 1px solid #BDBDBD !important;
border-bottom: 1px solid #BDBDBD !important;
color: #000 !important;
height: 20px !important;
padding: 0px;
}
.beijing-01__schedule .el-dialog .el-table tr td {
height: 20px !important;
padding: 0px;
}
.beijing-01__schedule .el-dialog .el-table .el-table__empty-text {
top: 15px !important;
}
.plan-schedule-dialog .el-dialog .current-row>td {
background: #316AC5 !important;
color: #fff !important;
}
.beijing-01__schedule .el-dialog .el-checkbox__inner {
border: 1px inset #dcdfe6 !important;
}
.beijing-01__schedule .el-dialog .el-checkbox__label {
color: #000 !important;
}
.beijing-01__schedule .el-dialog .el-checkbox.is-disabled .el-checkbox__inner {
background: #E6E6E6 !important;
}
.beijing-01__schedule .el-dialog .el-checkbox.is-disabled .el-checkbox__label {
color: #C5C9CC !important;
}
.beijing-01__schedule .el-dialog .el-checkbox__input.is-checked .el-checkbox__inner {
background: #fff !important;
border: 1px inset #dcdfe6 !important;
}
.beijing-01__schedule .el-dialog .el-checkbox__input.is-checked .el-checkbox__inner::after {
position: absolute;
-webkit-box-sizing: content-box;
box-sizing: content-box;
content: "";
border: 1px solid #000;
border-left: 0;
border-top: 0;
height: 7px;
left: 4px;
top: 1px;
}
.beijing-01__schedule .el-dialog .el-radio__inner {
border: 1px inset #dcdfe6 !important;
}
.beijing-01__schedule .el-dialog .el-radio__label {
color: #000 !important;
}
.beijing-01__schedule .el-dialog .el-radio__input.is-checked .el-radio__inner {
background: #fff !important;
border: 1px inset #dcdfe6 !important;
}
.beijing-01__schedule .el-dialog .el-radio__input.is-checked .el-radio__inner::after {
width: 4px;
height: 4px;
border-radius: 100%;
background-color: #000 !important;
position: absolute;
left: 50%;
top: 50%;
}
.beijing-01__schedule .el-dialog .el-radio.is-disabled .el-radio__inner {
background: #E6E6E6 !important;
}
.beijing-01__schedule .el-dialog .el-radio.is-disabled .el-radio__label {
color: #C5C9CC !important;
}
.beijing-01__schedule .el-dialog .base-label {
background: rgba(0, 0, 0, x);
position: relative;
left: -15px;
top: -18px;
}
.beijing-01__schedule .el-dialog .el-form-item label {
font-weight: normal !important;
color: #000 !important;
}
.beijing-01__schedule .el-dialog .context {
height: 100px;
border: 2px inset #E2E2E2;
overflow-y: scroll;
}
.beijing-01__schedule .el-dialog .table {
margin-top: 10px;
}
.beijing-01__schedule .el-dialog .notice {
margin-left: 62px;
line-height: 30px;
}
.beijing-01__schedule .el-dialog .button-group {
margin-top: 10px;
}
.beijing-01__schedule .el-dialog .el-tree__empty-block {
background: #E9E9E9 !important;
color: #000 !important;
}
</style>

View File

@ -0,0 +1,473 @@
<template>
<div id="PlanMenuBar">
<div class="nav">
<template v-for="(item,i) in menu">
<template v-if="noShowingChildren(item.children)">
<li class="nav-li" @click="hookClick(item)">
<span class="nav-li-text">{{ item.title }}</span>
</li>
</template>
<template v-else>
<li class="nav-li" @click.stop="popupMenuA(item, i)">
<span class="nav-li-text">{{ item.title }}</span>
<ul class="nav-ul" :class="{'active' :i==classA}">
<template v-for="(child,j) in item.children">
<template
v-if="child.children&&child.children.length>0&&hasShowingChildren(child.children)"
>
<li v-if="child.type === 'separator'" class="menu-separator">
<span class="status">&ensp;</span>
<span class="separator">&ensp;</span>
</li>
<li v-else-if="child.type === 'file'" class="menu-li">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<el-button type="text" class="button" :disabled="child.disabled">
<input
:ref="child.label"
type="file"
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@change="openLoadFile(child)"
>
{{ child.title }}
</el-button>
</span>
</div>
</li>
<li v-else class="menu-li" @click.stop="popupMenuB(child, j)">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<span class="label">{{ child.title }}</span>
</span>
</div>
<ul class="menu-ul" :class="{'active' :j==classB}">
<template v-for="(grandchild,k) in child.children">
<li v-if="grandchild.type === 'separator'" class="menu-separator">
<span class="status">&ensp;</span>
<span class="separator">&ensp;</span>
</li>
<li v-else-if="grandchild.type === 'file'" class="menu-li">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<el-button
type="text"
class="button"
:disabled="grandchild.disabled"
>
<input
:ref="grandchild.label"
type="file"
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@change="openLoadFile(grandchild)"
>
{{ grandchild.title }}
</el-button>
</span>
</div>
</li>
<li v-else class="menu-li" @click.stop="hookClick(grandchild)">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<span class="label">{{ grandchild.title }}</span>
</span>
</div>
</li>
</template>
</ul>
</li>
</template>
<template v-else>
<li v-if="child.type === 'separator'" class="menu-separator">
<span class="status">&ensp;</span>
<span class="separator">&ensp;</span>
</li>
<li v-else-if="child.type === 'file'" class="menu-li">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<el-button type="text" class="button" :disabled="child.disabled">
<input
:ref="child.title"
type="file"
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
@change="openLoadFile(child)"
>
{{ child.title }}
</el-button>
</span>
</div>
</li>
<li v-else class="menu-li" @click.stop="hookClick(child)">
<div class="menu-li-block">
<span class="menu-li-text">
<span class="status">&ensp;</span>
<span class="label">{{ child.title }}</span>
</span>
</div>
</li>
</template>
</template>
</ul>
</li>
</template>
</template>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { EventBus } from '@/scripts/event-bus';
export default {
name: 'PlanMenuBar',
props: {
lineCode: {
type: String,
required: true
}
},
data() {
return {
classA: -1,
classB: -1,
tempClassA: -1,
tempClassB: -1,
menu: [
{
title: '管理运行计划',
click: this.handleViewPlanSchedule
},
{
title: '仿真运行计划',
click: this.handleReloadTodayPlan
}
// {
// title: 'T',
// children: [
// {
// title: '',
// click: this.handleViewPlanSchedule
// },
// {
// title: '',
// click: this.handleCreateWeekPlan
// },
// {
// title: '',
// click: this.handleReloadTodayPlan
// }
// // {
// // title: '',
// // click: this.handleValidityCheck
// // }
// ]
// }
]
};
},
computed: {
...mapGetters('training', [
'mode'
]),
...mapGetters('map', [
'stationList'
])
},
watch: {
tempClassA() {
this.classA = this.$store.state.menuOperation.break ? -1 : this.tempClassA;
},
tempClassB() {
this.classB = this.$store.state.menuOperation.break ? -1 : this.tempClassB;
},
'$store.state.menuOperation.break': function (val) {
if (val) {
this.classA = this.classB = -1;
} else {
this.classA = this.tempClassA;
this.classB = this.tempClassB;
}
}
},
mounted() {
this.initMenu();
},
methods: {
initMenu() {
this.clickEvent();
this.closeMenu();
},
clickEvent() {
const self = this;
window.onclick = function (e) {
self.closeMenu(false);
};
},
noShowingChildren(children) {
if (!children || children.length <= 0) {
return true;
}
return false;
},
hasShowingChildren(children) {
if (children && children.length > 0) {
return true;
}
return false;
},
closeMenu() {
this.classA = this.tempClassA = -1;
this.classB = this.tempClassB = -1;
},
hookClick(item, event) {
this.closeMenu();
setTimeout(() => {
if (item && typeof item.click == 'function') {
item.click();
}
}, 500);
},
popupMenuA(item, index) {
this.clickEvent();
this.tempClassA = index;
this.tempClassB = -1;
},
popupMenuB(item, index) {
this.tempClassB = index;
},
openLoadFile(item) {
const obj = this.$refs[item.title][0];
if (obj.files) {
const file = obj.files[0];
item.click(file);
obj.value = '';
}
},
doClose() {
this.$nextTick(() => {
EventBus.$emit('closeMenu');
});
},
//
refresh() {
this.closeMenu(true);
EventBus.$emit('refresh');
},
undeveloped() {
this.doClose();
this.$alert('实现中......', '提示', {
confirmButtonText: '确定',
callback: action => {
}
});
},
//
handleEditPlanningTrain() {
this.$emit('dispatchDialog', { name: 'modifyingPlan' });
},
//
handleAddTask() {
const params = this.$store.state.runPlan.selected;
this.$emit('dispatchDialog', { name: 'addTask', params });
},
//
handleDeleteTask() {
const params = this.$store.state.runPlan.selected;
this.$emit('dispatchDialog', { name: 'deleteTask', params });
},
//
handleModifyingTask() {
const params = this.$store.state.runPlan.selected;
this.$emit('dispatchDialog', { name: 'modifyingTask', params });
},
//
handleModifyingPlanId() {
this.$emit('dispatchDialog', { name: 'modifyingPlanId' });
},
//
handleTranslationalMulTrain() {
this.$emit('dispatchDialog', { name: 'translationalMulTrain' });
},
//
handleViewPlanSchedule() {
this.$emit('dispatchDialog', { name: 'managePlanList' });
},
//
handleCreateWeekPlan() {
this.$emit('dispatchDialog', { name: 'createWeekPlan' });
},
//
handleReloadTodayPlan() {
this.$emit('dispatchDialog', { name: 'createTodayPlan' });
},
//
handleValidityCheck() {
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
$top: 25px;
$width: 30px;
$height: 20px;
$menuPadding: 10px;
$menuItemHeight: 30px;
$menuItemWidth: 160px;
$menuItemPadding: 5px;
#PlanMenuBar {
z-index: 10;
position: absolute;
top: $top;
width: 100%;
height: $height;
line-height: $height;
}
.nav {
display: block;
cursor: pointer;
color: #0000;
background: #EBEADB;
list-style: none;
border: 1px solid #B6BCCC !important;
}
.nav-li {
position: relative;
display: inline-block;
padding-left: $menuPadding;
padding-right: $menuPadding;
}
.nav-li:active {
background: #C9D0E1;
border-radius: 4px;
}
.nav-li-text {
font-size: 13px;
color: #000;
text-align: center;
text-decoration: none;
}
.nav-ul {
display: none;
position: absolute;
list-style: none;
border: 1px solid gray;
width: $menuItemWidth;
padding: 0px;
margin: 0px;
}
.menu-ul {
display: none;
list-style: none;
background: #F0F0F0;
line-height: $menuItemHeight;
width: $menuItemWidth;
bottom: $menuItemHeight;
}
.active {
position: absolute;
display: block !important;
}
.menu-ul-text {
font-size: 14px;
color: #000;
letter-spacing: 0;
height: $menuItemHeight;
line-height: $menuItemHeight;
border-left: 1px solid #000;
border-right: 1px solid #000;
}
.menu-separator {
text-align: left;
background: #F0F0F0;
height: 2px;
line-height: 2px;
}
.menu-separator .status {
display: inline-block;
border-right: 1px inset #CACACA;
width: $width;
height: 100%;
background: #EFECDE;
}
.menu-separator .separator {
display: inline-block;
background: #CACACA;
margin-left: 5px;
height: 2px;
width: $menuItemWidth - $width - 30px;
}
.menu-li {
text-align: left;
background: #F0F0F0;
height: $menuItemHeight;
line-height: $menuItemHeight;
}
.menu-li-block {
letter-spacing: 0;
height: $menuItemHeight;
line-height: $menuItemHeight;
}
.menu-li-text {
font-size: 14px;
color: #000;
}
.menu-li-text .status {
display: inline-block;
border-right: 1px inset #CACACA;
width: $width;
background: #EFECDE;
}
.menu-li-text .label {
display: inline-block;
margin-left: 5px;
}
.menu-li-text .button {
position: relative;
overflow: hidden;
margin-left: 10px;
line-height: 0px;
width: $menuItemWidth - $width;
top: -$menuItemHeight;
color: #000;
cursor: pointer;
input {
opacity: 0;
cursor: pointer;
position: absolute;
top: 0px;
width: $menuItemWidth - $width - 10px;
}
}
.menu-li-block:hover {
background: #C9DEF7;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,170 @@
<template>
<div id="PlanMenuTool">
<div class="nav">
<div v-for="(item,index) in tools" :key="index" class="tool">
<img :src="item.src" :alt="item.title">
</div>
</div>
</div>
</template>
<script>
import { prefixIntrger } from '@/utils/date';
import logo_ from '@/assets/logo_.png';
export default {
name: 'PlanMenuTool',
data() {
return {
tools: [
{
title: '服务器1',
operate: '',
src: logo_,
click: this.undeveloped
},
{
title: '服务器2',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '前置机1',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '前置机2',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '主调',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '调度台1',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '调度台2',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '调度台3',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '大屏',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '维护工作站',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '运行图显示人工站',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '跳停',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '扣车',
operate: '',
src: '',
click: this.undeveloped
},
{
title: '列车报警',
operate: '',
src: logo_,
click: this.undeveloped
}
]
};
},
computed: {
isShowSystemTime() {
return this.$route.params.mode == 'demon' || this.$route.params.mode === 'dp' || !this.$route.params.mode;
}
},
watch: {
'$store.state.training.initTime': function (initTime) {
const date = new Date(initTime);
this.time = `${prefixIntrger(date.getHours(), 2)}:${prefixIntrger(date.getMinutes(), 2)}${prefixIntrger(date.getSeconds(), 2)}`;
}
},
mounted() {
this.initTools();
},
methods: {
initTools() {
this.tools = [];
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
$top: 48px;
$width: 25px;
$height: 25px;
#PlanMenuTool {
z-index: 5;
position: absolute;
width: 100%;
top: $top;
}
.nav {
display: block;
color: #0000;
background: #EBEADB;
border: 1px solid #B6BCCC !important;
border-bottom: 2px solid #B6BCCC !important;
list-style: none;
height: $height;
line-height: $height;
}
.tool {
padding-left: 10px;
display: flex;
justify-content: center;
cursor: pointer;
position: relative;
float: left;
margin: 1px;
width: $width;
img {
display: block;
text-align: center;
padding-top: 2px;
height: $height - 5;
width: $width - 5;
}
}
</style>

View File

@ -0,0 +1,206 @@
<template>
<div v-if="show">
<template v-if="maxmini">
<div class="nav">
<div v-show="config.showClose" class="cls-status" @click="touch('Close')"><span /></div>
<div class="min-status" @click="touch('Minim')"><span /></div>
</div>
<el-table
ref="table"
:data="config.data"
:highlight-current-row="config.highlightCurrentRow"
:height="height"
border
@current-change="handleChange"
>
<template v-for="(item,index) in config.columns">
<el-table-column :key="index" :prop="item.prop" :label="item.label" :width="item.width" />
</template>
</el-table>
</template>
<template v-else>
<div class="nav">
<div class=" max-status" @click="touch('Maxim')"><span /></div>
</div>
</template>
</div>
</template>
<script>
export default {
name: 'DataTable',
props: {
height: {
type: Number,
required: true
},
config: {
type: Object,
required: true
}
},
data() {
return {
show: true,
maxmini: true,
touchStrategy: {
'Close': [false, true],
'Minim': [true, false],
'Maxim': [true, true]
}
};
},
methods: {
handleChange(row) {
if (this.config.handleChange) {
this.config.handleChange(row);
}
},
setCurrentRow(row) {
this.$refs.table.setCurrentRow(row);
},
touch(operate) {
this.$nextTick(() => {
[this.show, this.maxmini] = this.touchStrategy[operate];
this.$emit('touch', this.maxmini);
});
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
$height: 20px;
$width: 20px;
.nav {
display: table;
float: right;
width: 100%;
color: #0000;
background: -webkit-linear-gradient(#FDFDFE, #B1CBF3);
background: -o-linear-gradient(#FDFDFE, #B1CBF3);
background: -moz-linear-gradient(#FDFDFE, #B1CBF3);
background: linear-gradient(#FDFDFE, #B1CBF3);
border: 1px solid #B6BCCC !important;
border-bottom: 2px solid #B6BCCC !important;
list-style: none;
height: $height;
line-height: $height;
}
/deep/ {
.el-table--border th.gutter {
background: #EBEADB !important;
}
.el-table {
overflow-y: hidden;
width: 100%;
th.is-leaf {
padding: 0px 0;
background: #EBEADB;
border-right: none !important;
border-left: 1px solid #D1CDBD !important;
border-top: 1px solid #D1CDBD !important;
border-bottom: 1px inset #D1CDBD !important;
color: #000;
.cell {
height: $height;
line-height: $height;
}
}
td {
padding: 0px 0;
.cell {
height: $height;
line-height: $height;
font-size: smaller !important;
}
}
.current-row>td {
background: #316AC5 !important;
color: #fff !important;
}
}
.cls-status {
float: right;
width: 12px;
height: 100%;
line-height: 100%;
margin-left: 5px;
cursor: pointer;
span {
display: inline-block;
content: '/';
background: black;
width: 2px;
height: 12px;
vertical-align: middle;
transform: rotate(45deg);
}
span::after {
display: block;
content: '/';
background: black;
width: 2px;
height: 12px;
transform: rotate(-90deg);
}
}
.min-status {
float: right;
width: 20px;
height: 100%;
line-height: 100%;
cursor: pointer;
span {
display: inline-block;
content: '-';
background: black;
width: 2px;
height: 12px;
vertical-align: middle;
transform: rotate(-90deg);
}
}
.max-status {
float: right;
width: 20px;
height: 100%;
line-height: 100%;
cursor: pointer;
span {
display: inline-block;
content: '';
background: black;
width: 2px;
height: 12px;
transform: rotate(0deg);
}
span::after {
display: block;
content: '';
background: black;
width: 2px;
height: 12px;
transform: rotate(90deg);
}
}
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<el-dialog
v-dialogDrag
:title="title"
class="plan-schedule-dialog"
:visible.sync="dialogShow"
width="80%"
:before-close="doClose"
:modal="false"
:close-on-click-modal="false"
>
<el-table :data="tableData" border>
<el-table-column
type="index"
label="序号"
width="50"
/>
<el-table-column
property="name"
align="center"
label="运行图名称"
/>
<el-table-column
property="$loading"
align="center"
label="本次仿真加载"
>
<template slot-scope="scope">
<el-tag :type="scope.row.$loading?success:danger">{{ scope.row.$loading? '是': '否' }}</el-tag>
</template>
</el-table-column>
<el-table-column
fixed="right"
label="操作"
align="center"
width="150"
>
<template slot-scope="scope">
<el-button type="primary" :loading="loading" size="small" @click="handleClickLoad(scope.row)">加载</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="center" style="margin-top: 10px">
<el-button size="small" @click="dialogShow = false"> </el-button>
</el-row>
</el-dialog>
</template>
<script>
import { queryRunPlanList } from '@/api/runplan';
import { simulationLoadRunPlan } from '@/api/simulation';
export default {
name: 'ReloadTodayPlan',
data() {
return {
dialogShow: false,
loading: false,
tableData: [],
currentModel: {},
currentPlanId: ''
};
},
computed: {
title() {
return '管理本次仿真运行计划';
}
},
methods: {
doShow() {
this.loading = false;
this.dialogShow = true;
this.initPageData();
},
doClose() {
this.dialogShow = false;
},
initPageData() {
this.tableData = [];
queryRunPlanList(this.$route.query.mapId).then(resp =>{
if (resp.data && resp.data.length) {
resp.data.forEach(item => {
this.$set(item, '$loading', this.currentPlanId === item.id);
this.tableData.push({item});
});
}
}).catch(() => {
this.$message.error('获取地图模板运行图列表失败!');
});
},
handleClickLoad(row) {
this.loading = true;
simulationLoadRunPlan(this.$route.query.group, row.id).then(response => {
this.$message.success('仿真加载指定运行计划成功!');
this.tableData.forEach(item => {
item.$loading = item.id === row.id;
});
this.loading = false;
}).catch(() => {
this.$message.error('仿真加载指定运行计划失败!');
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
</style>

View File

@ -0,0 +1,132 @@
<template>
<el-dialog
v-dialogDrag
class="plan-schedule-dialog"
:title="title"
:visible.sync="dialogShow"
width="80%"
:before-close="doClose"
:z-index="2000"
:modal="false"
:close-on-click-modal="false"
>
<QueryListPage ref="queryListPage" :pager-config="pagerConfig" :query-form="queryForm" :query-list="queryList" />
</el-dialog>
</template>
<script>
import { getRunPlanLoadList, deleteRunPlanLoad, listAllTempLateRunPlan } from '@/api/runplan';
export default {
name: 'ManagePlanList',
data() {
return {
dialogShow: false,
loading: false,
pagerConfig: {
pageSize: 'pageSize',
pageIndex: 'pageNum'
},
queryForm: {
labelWidth: '140px',
reset: true,
offsetSpan: 20
},
queryList: {
query: this.queryFunction,
selectCheckShow: false,
indexShow: true,
columns: [
{
title: this.$t('publish.runPlanName'),
prop: 'templatePlanId',
type: 'tag',
columnValue: (row) => { return this.$convertField(row.templatePlanId, this.templatePlanList, ['id', 'name']); },
tagType: (row) => { return 'success'; }
},
{
title: '加载日期',
prop: 'loadTime'
},
{
type: 'button',
title: '操作',
width: '100',
buttons: [
{
name: '删除',
handleClick: this.handleDelete,
type: 'danger'
}
]
}
],
actions: [
{ text: '创建', btnCode: 'employee_insert', handler: this.handleCreateRunPlan }
]
},
currentModel: {}
};
},
computed: {
title() {
return '管理运行图计划表';
}
},
mounted() {
this.loadPageData();
},
methods: {
loadPageData() {
this.templatePlanList = [];
listAllTempLateRunPlan().then(resp => {
this.templatePlanList = resp.data;
});
},
queryFunction(params) {
if (this.$route.query.mapId) {
params['mapId'] = this.$route.query.mapId;
}
if (this.$store.state.user.id) {
params['userId'] = this.$store.state.user.id;
}
return getRunPlanLoadList(params);
},
handleDelete(index, row) {
this.$confirm('此操作将删除次日加载的运行图, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteRunPlanLoad(row.id).then(response => {
this.$message.success('删除成功');
this.reloadTable();
}).catch(() => {
this.reloadTable();
this.$messageBox('删除失败');
});
}).catch(() => { });
},
handleCreateRunPlan() {
this.$emit('dispatchDialog', { name: 'createWeekPlan' });
},
doShow() {
this.dialogShow = true;
this.$nextTick(()=> { this.reloadTable(); });
},
doClose() {
this.loading = false;
this.dialogShow = false;
},
reloadTable() {
this.queryList.reload();
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
/*@import "src/styles/mixin.scss";*/
</style>

View File

@ -0,0 +1,479 @@
<template>
<div id="PlanSchedule" :style="{top: top+'px', height: height+'px'}">
<div class="left">
<div :id="runPlanId" />
</div>
<div class="right">
<data-table
ref="serviceTable"
:height="height/2"
:config="serviceNumberConfig"
:style="{top: top-height/2+'px'}"
@touch="scheduleTouch"
/>
<data-table
ref="tripTable"
:height="height/2"
:config="tripNumberConfig"
:style="{top: top-height/2+'px'}"
@touch="trainNumTouch"
/>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { timeFormat } from '@/utils/date';
import DataTable from './menusPlan/components/dataTable';
import echarts from 'echarts';
import {toTimeStamp, formatDuring} from '@/utils/date';
export default {
name: 'PlanSchedule',
components: {
DataTable
},
props: {
group: {
type: String,
required: true
},
lineCode: {
type: String,
required: true
},
maxWidth: {
type: Number,
require: true
},
maxHeight: {
type: Number,
required: true
}
},
data() {
return {
top: 0,
height: 0,
heights: [100, 100],
runPlanId: 'plan-schedule-id',
myChart: null,
PlanConvert: {},
serviceNumberConfig: {
data: [],
highlightCurrentRow: true,
handleChange: this.serviceNumberChange,
showClose: false,
columns: [
{
prop: 'serviceNumber',
label: '表号'
},
{
width: 40
}
]
},
tripNumberConfig: {
data: [],
highlightCurrentRow: true,
handleChange: this.tripNumberChange,
showClose: false,
columns: [
{
prop: 'tripNumber',
label: '车次号'
},
{
width: 40
}
]
},
realData: {},
kmRangeCoordMap: {},
option: {
title: {
text: '',
left: 'center'
},
grid: {
top: '30px',
left: '120px',
right: '40px',
bottom: '65px',
containLabel: true,
backgroundColor: 'floralwhite'
},
toolbox: {
// right: '30px',
// feature: {
// dataZoom: {
// yAxisIndex: 'none'
// },
// restore: {},
// saveAsImage: {}
// }
},
tooltip: {
axisPointer: {
trigger: 'item',
type: 'cross'
},
formatter: this.axisTooltip,
borderWidth: 1
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: [],
axisLine: {
onZero: false,
lineStyle: {
width: 2,
color: '#d14a61'
}
},
axisLabel: {
formatter: this.xAxisLableFormat,
textStyle: {
color: '#333'
}
},
axisPointer: {
snap: true,
label: {
formatter: this.xAxisPointFormat,
backgroundColor: 'rgb(255,0,0,0.5)',
color: 'white'
}
}
}
],
yAxis: {
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
onZero: false,
lineStyle: {
width: 2,
color: '#d14a61'
}
},
axisLabel: {
interval: 'auto',
formatter: this.yAxisLableFormat
},
axisPointer: {
xAxisIndex: 'all',
label: {
formatter: this.yAxisPointFormat,
backgroundColor: 'rgb(0,100,0,0.5)',
color: 'white'
}
},
min: 0,
max: 0
},
series: [],
dataZoom: [
{
type: 'inside'
},
{
fiterMode: 'filter',
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
},
bottom: '20px'
}
]
},
absoluteTime: 2 * 3600,
indexKmRangeMap: {}
};
},
watch: {
maxWidth() {
this.setPosition();
},
maxHeight() {
this.setPosition();
},
'$store.state.runPlan.planLoadedCount': async function () {
await this.loadChartPage();
},
'$store.state.runPlan.planSizeCount': function () {
this.reSize({ width: this.$store.state.runPlan.width, height: this.$store.state.runPlan.height });
},
'$store.state.runPlan.selected.serviceNumber': function (val) {
const index = this.serviceNumberConfig.data.findIndex(elem => {
return elem.serviceNumber == val;
});
this.$refs.serviceTable.setCurrentRow(this.serviceNumberConfig.data[index]);
},
'$store.state.runPlan.selected.tripNumber': function (val) {
const index = this.tripNumberConfig.data.findIndex(elem => {
return elem.tripNumber == val;
});
this.$refs.tripTable.setCurrentRow(this.tripNumberConfig.data[index]);
}
},
computed: {
...mapGetters('runPlan', [
'stations'
])
},
mounted() {
this.PlanConvert = this.$theme.loadPlanConvert(this.lineCode);
},
beforeDestroy() {
this.destroy();
},
methods: {
serviceNumberChange(row) {
if (row) {
this.$store.dispatch('runPlan/setSelected', { serviceNumber: row.serviceNumber, tripNumber: null });
const serviceObj = this.$store.state.runPlan.editData[row.serviceNumber];
if (serviceObj) {
this.analyticalTripNumber(serviceObj.trainMap);
}
}
},
tripNumberChange(row) {
if (row) {
this.$store.dispatch('runPlan/setSelected', { serviceNumber: this.$store.state.runPlan.selected.serviceNumber, tripNumber: row.tripNumber });
}
},
async analyticalServiceNumber(data) {
this.serviceNumberConfig.data = Object.keys(data || {})
.sort((a, b) => { return data[a].oldIndex - data[b].oldIndex; })
.map(serviceNumber => { return { serviceNumber }; });
},
async analyticalTripNumber(data) {
this.tripNumberConfig.data = Object.keys(data || {})
.sort((a, b) => { return data[a].oldIndex - data[b].oldIndex; })
.map(tripNumber => { return { tripNumber }; });
},
async setPosition() {
this.$nextTick(() => {
let top = 3;
const width = this.maxWidth * 0.85;
let height = this.maxHeight;
const titleBar = document.getElementById('PlanTitleBar');
const menuBar = document.getElementById('PlanMenuBar');
const menuTool = document.getElementById('PlanMenuTool');
const statusBar = document.getElementById('PlanStatusBar');
if (titleBar) {
top += (titleBar.offsetHeight || 0);
}
if (menuBar) {
top += (menuBar.offsetHeight || 0);
}
if (menuTool) {
top += (menuTool.offsetHeight || 0);
}
if (statusBar) {
height -= (statusBar.offsetHeight || 0);
}
height = height - top;
this.$store.dispatch('runPlan/resize', { width, height });
if (this.top != top) {
this.top = top;
}
if (this.height != height) {
this.height = height - 20 * 2;
}
});
},
async loadChartPage() {
try {
let series = [];
const stations = this.$store.state.runPlan.stations;
const planData = this.$store.state.runPlan.planData;
this.viewDisabled = true;
this.kmRangeCoordMap = this.PlanConvert.convertStationsToMap(stations);
series = this.pushModels(series, [this.PlanConvert.initializeYaxis(stations)]);
series = this.pushModels(series, this.PlanConvert.convertDataToModels(planData, stations, this.kmRangeCoordMap, { color: '#000', width: 0.5 }));
await this.loadInitData(series);
await this.analyticalServiceNumber(this.$store.state.runPlan.editData);
this.viewDisabled = false;
} catch (error) {
this.viewDisabled = false;
this.$messageBox(`加载运行图数据失败`);
}
},
async loadInitData(series) {
this.myChart && this.myChart.showLoading();
await this.xAxisInit();
await this.yAxisInit();
await this.loadInitChart(series);
this.myChart && this.myChart.hideLoading();
},
pushModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
if (elem) {
series.push(elem);
}
});
}
return series;
},
popModels(series, models) {
if (models && models.length) {
models.forEach(elem => {
const index = series.indexOf(elem);
if (index >= 0) {
series.split(index, 1);
}
});
}
return series;
},
loadInitChart(series) {
return new Promise((resolve, reject) => {
try {
this.destroy();
let startValue = 3600 + this.PlanConvert.TranslationTime;
const offsetTime = 3600;
const initTime = toTimeStamp(formatDuring(this.$store.state.training.initTime));
startValue = initTime - this.PlanConvert.TranslationTime;
this.option.dataZoom[0].startValue = this.option.dataZoom[1].startValue = startValue - offsetTime;
this.option.dataZoom[0].endValue = this.option.dataZoom[1].endValue = startValue + offsetTime;
this.option.series = series;
this.myChart = echarts.init(document.getElementById(this.runPlanId));
if (this.myChart) {
this.myChart.setOption(this.option);
this.reSize({ width: this.$store.state.runPlan.width, height: this.$store.state.runPlan.height });
this.myChart.on('click', this.mouseClick);
}
resolve(true);
} catch (error) {
reject(error);
}
});
},
xAxisPointFormat(params) {
return timeFormat(params.value);
},
yAxisPointFormat(params) {
return this.PlanConvert.computedFormatYAxis(this.stations, params);
},
xAxisLableFormat(value, index) {
if (value % 60 === 0) {
return timeFormat(value);
}
},
yAxisLableFormat(value, index) {
return '';
},
xAxisInit() {
const list = [];
for (var time = 0 + this.PlanConvert.TranslationTime; time < 3600 * 24 + this.PlanConvert.TranslationTime; time++) {
list.push(time);
}
const startValue = 3600 * 6;
const offsetTime = 3600 * 1;
this.option.xAxis[0].data = list;
if (!this.option.dataZoom[0].startValue) {
this.option.dataZoom[0].startValue = this.option.dataZoom[1].startValue = startValue - offsetTime;
}
if (!this.option.dataZoom[0].endValue) {
this.option.dataZoom[0].endValue = this.option.dataZoom[1].endValue = startValue + offsetTime;
}
},
yAxisInit() {
if (Object.keys(this.PlanConvert).length) {
this.option.yAxis.min = this.PlanConvert.computedYaxisMinValue(this.stations);
this.option.yAxis.max = this.PlanConvert.computedYaxisMaxValue(this.stations);
}
},
axisTooltip(param) {
const station = this.stations[Math.floor((param.data[1] - this.PlanConvert.EdgeHeight) / this.PlanConvert.CoordMultiple)] || { name: '', kmRange: '' };
return [
`Point Data <hr size=1 style=" margin: 3px 0">`,
`车站名称: ${station.name}<br>`,
`车站公里标: ${station.kmRange} km <br>`,
`到站时间: ${timeFormat(param.data[0] + this.PlanConvert.TranslationTime)} (${param.data[0]})<br>`
].join('');
},
mouseClick(params) {
const model = {
serviceNumber: params.seriesName
};
this.$store.dispatch('runPlan/setSelected', model);
},
reSize(opt) {
if (this.myChart) {
this.myChart.resize({
width: opt.width,
height: opt.height,
silent: false
});
}
},
destroy() {
if (this.myChart && this.myChart.isDisposed) {
this.myChart.dispose();
this.myChart = null;
}
},
scheduleTouch() {
},
trainNumTouch() {
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss">
@import "src/styles/mixin.scss";
#PlanSchedule {
z-index: 5;
position: absolute;
width: 100%;
.left {
height: 100%;
width: 85%;
float: left;
}
.right {
height: 100%;
width: 15%;
float: right;
}
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<data-table
id="PlanStatusBar"
ref="dataTable"
:height="height-11"
:config="stationListConfig"
:close="false"
:style="{top: maxmini? maxTop-110+'px':maxTop-21+'px'}"
@touch="touch"
/>
</template>
<script>
import DataTable from './menusPlan/components/dataTable';
import { formatTime, formatName } from '@/utils/runPlan';
export default {
name: 'PlanStatusBar',
components: {
DataTable
},
props: {
maxTop: {
type: Number,
required: true
}
},
data() {
return {
maxmini: true,
height: 100,
stationListConfig: {
data: [],
showClose: true,
highlightCurrentRow: true,
columns: [
{
prop: 'stationName',
label: '站台',
width: 400
},
{
prop: 'startTime',
label: '到点'
},
{
prop: 'stopTime',
label: '停站时间'
},
{
prop: 'endTime',
label: '发点'
},
{
prop: 'level',
label: '运行等级'
}
]
}
};
},
watch: {
'$store.state.runPlan.selected': function (select) {
this.stationListConfig.data = [];
const serviceObj = this.$store.state.runPlan.editData[select.serviceNumber];
if (serviceObj) {
const trainMap = serviceObj.trainMap;
if (trainMap) {
const trainObj = trainMap[select.tripNumber];
if (trainObj) {
const stationTimeList = trainObj.stationTimeList;
if (stationTimeList && stationTimeList.length) {
stationTimeList.forEach((elem, index) => {
const stationObj = {
stationName: formatName(elem.stationCode),
startTime: formatTime(index == 0 ? null : stationTimeList[index - 1].secondTime),
stopTime: formatTime(index == 0 ? null : elem.secondTime - stationTimeList[index - 1].secondTime),
endTime: formatTime(elem.secondTime),
level: ''
};
this.stationListConfig.data.push(stationObj);
});
}
}
}
}
}
},
methods: {
touch(maxmini) {
this.maxmini = maxmini;
this.$emit('setPosition');
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
#PlanStatusBar {
z-index: 5;
position: absolute;
width: 100%;
}
</style>

View File

@ -0,0 +1,75 @@
<template>
<div id="PlanTitleBar">
<img class="logo" :src="logoImg">
<span> {{ mapName }} &ensp;</span>
<span v-if="runPlanName">({{ runPlanName }})</span>
<span class="system-close el-icon-close" @click="back" />
</div>
</template>
<script>
import logo_ from '@/assets/logo_.png';
import { getPublishMapInfo } from '@/api/jmap/map';
export default {
name: 'PlanTitleBar',
data() {
return {
mapName: '',
logoImg: logo_
};
},
computed: {
runPlanName() {
return this.$route.query.planName || '';
}
},
mounted() {
if (this.$route.query.mapId) {
getPublishMapInfo(this.$route.query.mapId).then(resp => {
this.mapName = resp.data.name;
});
}
},
methods: {
back() {
this.$emit('back');
}
}
};
</script>
<style scoped rel="stylesheet/scss" lang="scss" scoped>
@import "src/styles/mixin.scss";
$width: 25px;
$height: 25px;
#PlanTitleBar {
z-index: 10;
display: flex;
position: absolute;
width: 100%;
height: $height;
line-height: $height;
background: -webkit-linear-gradient(#0055E8, #0099F8);
background: -o-linear-gradient(#0055E8, #0099F8);
background: -moz-linear-gradient(#0055E8, #0099F8);
background: linear-gradient(#0055E8, #0099F8);
color: white;
font: bold;
font-size: 16px;
.logo {
display: inline-block;
width: $width;
height: $height;
padding-right: 5px;
}
.system-close {
width: 25px;
height: 25px;
position: absolute;
right: 1px;
}
}
</style>