This commit is contained in:
fan 2022-09-20 14:22:44 +08:00
parent 62d864d996
commit 91c04e97b1
6 changed files with 904 additions and 12 deletions

View File

@ -0,0 +1,138 @@
<template>
<el-dialog
v-dialogDrag
:title="title"
:visible.sync="dialogVisible"
width="500px"
:before-close="handleClose"
center
:close-on-click-modal="false"
>
<el-form ref="form" :model="formModel" label-width="120px" :rules="rules">
<el-form-item label="添加仿真成员:" prop="type">
<el-select v-model="formModel.type" placeholder="请选择" size="small">
<el-option
v-for="item in typeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="stationRoleList.includes(formModel.type)" label="值班车站:" prop="deviceCode">
<el-select v-model="formModel.deviceCode" placeholder="请选择" size="small">
<el-option
v-for="item in filterStationList"
:key="item.code"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="仿真成员名称:" prop="name">
<el-input v-model="formModel.name" size="small" placeholder="请输入成员名称" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="doSave">{{ $t('global.confirm') }}</el-button>
<el-button @click="handleClose">{{ $t('global.cancel') }}</el-button>
</span>
</el-dialog>
</template>
<script>
import { addSimulationMember } from '@/api/jointSimulation';
export default {
name: 'AddMember',
props: {
stationList: {
type: Array,
required: true
}
},
data() {
return {
dialogVisible: false,
formModel: {
type: '',
name: '',
deviceCode: ''
},
filterStationList: [],
rules: {
type: [
{ required: true, message: '请选择显示位置', trigger: 'change' }
],
deviceCode: [
{ required: true, message: '请选择值班车站', trigger: 'change' }
]
},
stationRoleList:[
'STATION_SUPERVISOR',
'STATION_ASSISTANT',
'STATION_MASTER',
'STATION_SIGNALER',
'STATION_PASSENGER',
'STATION_SWITCH_MAN',
'STATION_FACILITATOR',
'STATION_WORKER',
'DEVICE_MANAGER'
],
typeList: [
{label: '行调', value: 'DISPATCHER'},
{label: '通号', value: 'MAINTAINER'},
{label: '车站值班员', value: 'STATION_SUPERVISOR'},
{label: '车站助理', value: 'STATION_ASSISTANT'},
{label: '车站站长', value: 'STATION_MASTER'},
{label: '车站信号员', value: 'STATION_SIGNALER'},
{label: '车站客运员', value: 'STATION_PASSENGER'},
{label: '车站扳道员', value: 'STATION_SWITCH_MAN'},
{label: '车站引导员', value: 'STATION_FACILITATOR'},
{label: '车站工务工', value: 'STATION_WORKER'},
{label: '设备管理员', value: 'DEVICE_MANAGER'},
{label: '车务段段长', value: 'TRAIN_MASTER'}
]
};
},
computed: {
title() {
return '添加仿真角色成员';
}
},
methods: {
initData(row) {
this.filterStationList = [];
this.stationList.forEach(item => {
if (!item.depot) {
this.filterStationList.push(item);
}
});
},
doShow(row) {
this.initData(row);
this.dialogVisible = true;
},
doSave() {
this.$refs.form.validate(() => {
// if (this.formModel.type !== 'STATION_SUPERVISOR') { delete this.formModel.deviceCode; }
if (!this.stationRoleList.includes(this.formModel.type)) { delete this.formModel.deviceCode; }
addSimulationMember(this.formModel, this.$route.query.group).then(() => {
this.$message.success('添加仿真角色成员成功!');
this.handleClose();
}).catch(() => {
this.$message.error('添加仿真角色成员失败!');
});
});
},
handleClose() {
this.dialogVisible = false;
this.formModel = {
type: '',
name: '',
deviceCode: ''
};
this.$refs.form.resetFields();
}
}
};
</script>

View File

@ -0,0 +1,100 @@
<template>
<div class="jointRoomMenu">
<pop-menu ref="popMenu" :menu="menu" />
</div>
</template>
<script>
import PopMenu from '@/components/PopMenu';
import { DeviceMenu } from '@/scripts/ConstDic';
import { kickOutMember } from '@/api/jointSimulation';
export default {
components: {
PopMenu
},
props: {
clickUserId: {
type: String,
default: ''
},
menuDisabled: {
type: Boolean,
default: false
}
},
data() {
return {
// menu: [{
// label: this.$t('trainRoom.kickOutTheRoom'),
// handler: this.kicked
// }]
};
},
computed: {
userId() {
return this.$store.state.user ? this.$store.state.user.id : '';
},
position() {
return this.$store.state.menuOperation.menuPosition;
},
menu() {
return [{
label: this.$t('trainRoom.kickOutTheRoom'),
handler: this.kicked,
disabled: this.menuDisabled
}];
}
},
watch: {
'$store.state.menuOperation.menuCount': function (val) {
if (this.$store.getters['menuOperation/checkDialogIsOpen'](DeviceMenu.JointRoom)) {
this.doShow();
} else {
this.doClose();
}
}
},
mounted() {
this.closeEvent();
},
beforeDestroy() {
window.removeEventListener('click', this.doClose, false);
},
methods: {
closeEvent() {
window.addEventListener('click', this.doClose, false);
},
doShow() {
this.closeEvent();
if (this.userId != this.clickUserId) {
if (this.$refs && this.$refs.popMenu) {
this.$refs.popMenu.resetShowPosition(this.position);
}
}
},
doClose() {
if (this.$refs && this.$refs.popMenu) {
this.$refs.popMenu.close();
}
},
async kicked() {
try {
await kickOutMember(this.$route.query.group, this.clickUserId);
} catch (error) {
console.error(error);
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
/deep/ {
.menu-item{
background: #f1ecec;
.pop-menu {
background: #5F9EA0;
}
}
}
</style>

View File

@ -0,0 +1,157 @@
<template>
<div class="member">
<div class="member__head">
<div class="member__head--title"> 仿真用户列表</div>
<div class="member__head--notes"> {{ onlineNum }}/{{ members.length }}</div>
</div>
<div class="member__container">
<el-input v-model="filterText" :placeholder="this.$t('global.enterNameToFilter')" clearable />
<el-scrollbar class="member__container--list" wrap-class="scrollbar-wrapper" style="{height: calc(100% - 64px)}">
<el-tree
ref="tree"
:data="filterMembers"
:filter-node-method="handleFilterNode"
:lazy="false"
:props="defaultProps"
@node-contextmenu="handleShowContextMenu"
>
<span slot-scope="{ node, data }">
<span v-if="node.data.online" style="color: green;">{{ data.nickName + (data.admin? '管理员':'') + (data.referee? '裁判员':'') + (data.deviceVO? ` -- (${data.deviceVO.code})`:'') }}</span>
<span v-else style="color: #ccc;">{{ data.nickName + (data.admin? '【管理员】':'') + (data.referee? '【裁判员】':'') + (data.deviceVO? ` -- (${data.deviceVO.code})`:'') }}</span>
</span>
</el-tree>
</el-scrollbar>
</div>
<content-menu ref="menu" :click-user-id="clickUserId" :menu-disabled="menuDisabled" />
</div>
</template>
<script>
import { DeviceMenu } from '@/scripts/ConstDic';
import ContentMenu from './content-menu';
export default {
components: {
ContentMenu
},
props: {
room: {
type: Object,
required: true
},
members: {
type: Array,
required: true
},
isAdmin: {
type: Boolean,
default() {
return false;
}
}
},
data() {
return {
filterText: '',
clickUserId: '',
menuDisabled: false,
onlineNum: 1
};
},
computed: {
defaultProps() {
return { label: 'nickName' };
},
filterMembers() {
return this.members.filter(e =>{ return e.nickName.includes(this.filterText); });
},
userId() {
return this.$store.state.user ? this.$store.state.user.id : '';
}
},
watch: {
members: {
handler(n, o) {
let num = 0;
if (n && n.length) {
n.forEach(item => {
if (item.online) {
num++;
}
});
}
this.onlineNum = num;
},
immediate: true,
deep: true
}
},
methods: {
handleFilterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
handleShowContextMenu(e, obj, node, vueElem) {
e.preventDefault();
const position = {
x: e.clientX,
y: e.clientY
};
if (this.isAdmin) {
this.clickUserId = `${obj.userId || ''}`;
this.menuDisabled = !!obj.deviceVO;
this.$store.dispatch('menuOperation/setPopMenu', { position, menu: DeviceMenu.JointRoom });
}
}
}
};
</script>
<style scoped lang="scss">
.member {
background: #f0f0f0;
display: flex;
flex-direction: column;
border: 1px solid #ccc;
&__head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
border-bottom: 1px solid #ccc;
&--title {
padding:10px 0px;
font-size: 16px;
font-weight: bold;
}
&--notes {
font-size: 16px;
padding:10px 0px;
display: flex;
align-items: flex-end;
}
}
&__container {
flex-grow: 1;
height: 520px;
&--list {
background: #fff;
height: calc(100% - 109px);
border-bottom: 1px #ccc solid;
&::-webkit-scrollbar {
display: none;
}
}
}
}
/deep/ {
.member__container{
height: calc(100% - 40px);
}
}
</style>

View File

@ -0,0 +1,484 @@
<template>
<el-drawer
title="仿真成员管理"
:visible.sync="show"
:direction="direction"
:before-close="doClose"
custom-class="drawer_box"
size="43%"
>
<div class="room">
<div class="room__container">
<div style="width: 70%;height: calc(100% - 20px);">
<div style="margin-left: 10px;margin-right: 10px;">
<el-input v-model="queryMember" placeholder="请输入搜索人员">
<el-button slot="append" icon="el-icon-search" />
</el-input>
<el-button @click="addMember">添加仿真成员</el-button>
</div>
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
default-expand-all
style="margin: 10px;margin-bottom: 0;border: 1px solid #ccc;overflow-y: auto;height: calc(100% - 120px);"
:filter-node-method="filterNode"
@node-click="handleNodeClick"
>
<span :id="data.id" slot-scope="{ data }" class="custom-tree-node">
<span>{{ data.labelName }}</span>
<span v-if="data.type">
<el-select :key="data.id" v-model="data.userId" placeholder="请选择" clearable size="mini" @change="nodeMemberChange($event, data)">
<el-option
v-for="item in simulationUserList"
:key="item.userId"
:label="item.nickName"
:value="item.userId"
/>
</el-select>
</span>
</span>
</el-tree>
</div>
<e-members
class="room__container--members"
:room="room"
:members="simulationUserList"
:is-admin="isAdmin"
style="height: 100%"
@message="messageInfo"
/>
</div>
<div class="room__footer" />
</div>
</el-drawer>
</template>
<script>
import eMembers from './e-members';
import { EventBus } from '@/scripts/event-bus';
import { assignUsersPlayRoles } from '@/api/jointSimulation';
export default {
name: 'MembersManage',
components: {
eMembers
},
props: {
isAdmin: {
type: Boolean,
default() {
return false;
}
}
},
data() {
return {
show: false,
direction: 'ltr',
queryMember: '',
room: {
totalNum: 0,
group: '',
mapId: '',
creatorId: '',
creator: {
nickName: ''
},
permissionRest: 0,
permissionNum: 0,
state: ''
},
defaultProps: {
children: 'children',
label: 'labelName'
},
simulationUserList: [],
stationList: [],
availableStationList:[],
activeTrains: [],
standList: [],
doorList: [],
memberData: {},
treeData: [{
labelName: '行调',
children: []
}, {
labelName: '车站值班员',
children: []
}, {
labelName: '司机',
children: []
}, {
labelName: '通号',
children: []
}, {
labelName: '车辆段',
children: []
}, {
labelName: 'CTC操作员',
children: []
}, {
labelName: '车站助理',
children: []
},
{
labelName: '车站站长',
children: []
},
{
labelName: '车站信号员',
children: []
},
{
labelName: '车站客运员',
children: []
},
{
labelName: '车站扳道员',
children: []
},
{
labelName: '车站引导员',
children: []
},
{
labelName: '车站工务工',
children: []
},
{
labelName: '设备管理员',
children: []
}
]
};
},
computed: {
height() {
return this.$store.state.app.height - 130;
},
group() {
return this.$route.query.group;
},
userId() {
return this.$store.state.user ? this.$store.state.user.id : '';
},
username() {
return this.$store.state.user.nickname;
}
},
watch: {
queryMember(val) {
this.$refs.tree.filter(val);
},
'$store.state.training.simulationUserList': function(val) {
this.simulationUserList = val;
},
'$store.state.training.memberList': function (val) {
if (val && val.length) {
this.memberData = this.$store.state.training.memberData;
const dispatcherList = [];
const electricDispatcherList = [];
const depotDispatcherList = [];
const stationSupervisorList = [];
const driverList = [];
const maintainerList = [];
const ctcOperatorList = [];
const stationAssistantList = [];
const stationMasterList = [];
const stationSignalerList = [];
const stationPassengerList = [];
const stationSwitchManList = [];
const stationFacilitatorList = [];
const stationWorkerList = [];
const deviceManagerList = [];
const trainMasterList = [];
val.forEach(item => {
const device = this.$store.getters['map/getDeviceByCode'](item.deviceCode);
switch (item.type) {
case 'DISPATCHER':
this.memberData[item.id].labelName = '行调' + (item.name || '');
dispatcherList.push(this.memberData[item.id]);
break;
case 'ELECTRIC_DISPATCHER':
this.memberData[item.id].labelName = '电力调度' + (item.name || '');
electricDispatcherList.push(this.memberData[item.id]);
break;
case 'DEPOT_DISPATCHER':
this.memberData[item.id].labelName = '车辆段信号楼' + (item.name || '');
depotDispatcherList.push(this.memberData[item.id]);
break;
case 'STATION_SUPERVISOR':
this.memberData[item.id].labelName = '值班员-' + device.name + (item.name ? `-${item.name }` : '');
stationSupervisorList.push(this.memberData[item.id]);
break;
case 'DRIVER':
this.memberData[item.id].labelName = '司机-列车' + item.deviceCode;
driverList.push(this.memberData[item.id]);
break;
case 'MAINTAINER':
this.memberData[item.id].labelName = '通号' + (item.name || '');
maintainerList.push(this.memberData[item.id]);
break;
case 'RAIL_CTC':
this.memberData[item.id].labelName = 'CTC操作员' + device.name;
ctcOperatorList.push(this.memberData[item.id]);
break;
case 'STATION_ASSISTANT':
this.memberData[item.id].labelName = '车站助理-' + device.name + (item.name ? `-${item.name }` : '');
stationAssistantList.push(this.memberData[item.id]);
break;
case 'STATION_MASTER':
this.memberData[item.id].labelName = '车站站长-' + device.name + (item.name ? `-${item.name }` : '');
stationMasterList.push(this.memberData[item.id]);
break;
case 'STATION_SIGNALER':
this.memberData[item.id].labelName = '车站信号员-' + device.name + (item.name ? `-${item.name }` : '');
stationSignalerList.push(this.memberData[item.id]);
break;
case 'STATION_PASSENGER':
this.memberData[item.id].labelName = '车站客运员-' + device.name + (item.name ? `-${item.name }` : '');
stationPassengerList.push(this.memberData[item.id]);
break;
case 'STATION_SWITCH_MAN':
this.memberData[item.id].labelName = '车站扳道员-' + device.name + (item.name ? `-${item.name }` : '');
stationSwitchManList.push(this.memberData[item.id]);
break;
case 'STATION_FACILITATOR':
this.memberData[item.id].labelName = '车站引导员-' + device.name + (item.name ? `-${item.name }` : '');
stationFacilitatorList.push(this.memberData[item.id]);
break;
case 'STATION_WORKER':
this.memberData[item.id].labelName = '车站工务工-' + device.name + (item.name ? `-${item.name }` : '');
stationWorkerList.push(this.memberData[item.id]);
break;
case 'DEVICE_MANAGER':
this.memberData[item.id].labelName = '设备管理员-' + device.name + (item.name ? `-${item.name }` : '');
deviceManagerList.push(this.memberData[item.id]);
break;
case 'TRAIN_MASTER':
// device.name;
this.memberData[item.id].labelName = '车务段段长-' + (item.name ? `-${item.name }` : '');
trainMasterList.push(this.memberData[item.id]);
break;
// DEVICE_MANAGER:'' deviceManager
}
});
this.treeData = [{
labelName: '行调',
id: 'dispatcher',
children: dispatcherList
}, {
labelName: '车站值班员',
id: 'stationSupervisor',
children: stationSupervisorList
}, {
labelName: '司机',
id: 'driver',
children: driverList
}, {
labelName: '通号',
id: 'maintainer',
children: maintainerList
}, {
labelName: '车辆段信号楼',
id: 'depotDispatcher',
children: depotDispatcherList
}, {
labelName: '电力调度',
id: 'electricDispatcher',
children: electricDispatcherList
}, {
labelName: 'CTC操作员',
id: 'ctcOperator',
children: ctcOperatorList
}, {
labelName: '车站助理',
id: 'stationAssistant',
children: stationAssistantList
},
{
labelName: '车站站长',
id: 'stationMaster',
children: stationMasterList
},
{
labelName: '车站信号员',
id: 'stationSignaler',
children: stationSignalerList
},
{
labelName: '车站客运员',
id: 'stationPassenger',
children: stationPassengerList
},
{
labelName: '车站扳道员',
id: 'stationSwitchMan',
children: stationSwitchManList
},
{
labelName: '车站引导员',
id: 'stationFacilitator',
children: stationFacilitatorList
},
{
labelName: '车站工务工',
id: 'stationWorker',
children: stationWorkerList
},
{
labelName: '设备管理员',
id: 'deviceManager',
children: deviceManagerList
},
{
labelName: '车务段段长 ',
id: 'trainMaster',
children: trainMasterList
}
];
EventBus.$emit('trainTicketMember', [...stationSupervisorList, ...stationAssistantList]);
this.$nextTick(() => {
if (this.$refs.tree) {
this.$refs.tree.filter(this.queryMember);
}
});
}
},
'$store.state.map.activeTrainListChange': function () {
this.activeTrains = [];
const activeTrainList = this.$store.state.map.activeTrainList;
if (activeTrainList && activeTrainList.length) {
activeTrainList.forEach(groupNumber => {
this.activeTrains.push(groupNumber);
});
}
this.$refs.tree && this.$refs.tree.filter(this.queryMember);
}
},
mounted() {
},
methods: {
doShow() {
this.show = true;
this.memberData = this.$store.state.training.memberData;
this.simulationUserList = this.$store.state.training.simulationUserList;
this.$nextTick(() => {
if (this.$refs.tree) {
this.$refs.tree.filter(this.queryMember);
}
});
},
doClose() {
this.show = false;
},
messageInfo(info) {
this.$message({ showClose: true, ...info });
},
jumpInSimulation() {
},
clearSubscribe() {
},
handleNodeClick() {
},
nodeMemberChange(val, nodeData) {
let user = '';
this.simulationUserList.forEach(item => {
if (val && item.userId === val) {
user = item;
} else if (!val && item.memberId === nodeData.id) {
user = item;
}
});
const data = [{userId: user.userId, memberId:val ? nodeData.id : ''}];
const self = this;
assignUsersPlayRoles(data, this.$route.query.group).then(resp => {
this.$message.success('调整角色成员成功!');
}).catch(() => {
self.memberData[nodeData.id].userId = '';
this.$message.error('调整角色成员失败!');
});
},
addMember() {
this.$emit('addSimulationMember');
},
filterNode(value, data) {
let flag = false;
if (this.memberData[data.id] && this.memberData[data.id].nickName) {
flag = this.memberData[data.id].nickName.indexOf(value) !== -1;
}
let driverNoShow = true;
if (data.type && data.type === 'DRIVER' && !this.activeTrains.includes(data.deviceCode)) {
driverNoShow = false;
}
return (data.labelName.indexOf(value) !== -1 || flag) && driverNoShow;
}
// handlerMemberOnOff(data) {
// this.$store.dispatch('training/updateMemberAndUser', { simulationUserList: data, userId: this.userId });
// }
}
};
</script>
<style scoped lang="scss">
.drawer_box{
width: 800px;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
margin: 2px;
}
.room {
width: 100%;
height: 100%;
// display: flex;
// flex-direction: column;
box-sizing: border-box;
background: #f0f0f0;
&__container {
height: 100%;
display: flex;
flex-grow: 1;
padding: 10px;
&--members {
flex-shrink: 1;
flex-grow: 1;
}
&--roles {
flex-grow: 5;
flex-shrink: 5;
}
&--chat {
flex-basis: 360px;
}
}
&__footer {
height: 20px;
}
}
/deep/ {
.el-input--mini .el-input__inner {
height: 24px;
line-height: 24px;
}
.el-input-group {
width: calc(100% - 146px);
}
.el-dialog__body {
padding: 6px 20px;
}
.el-drawer__body{
height: 100%;
}
}
</style>

View File

@ -22,6 +22,7 @@
<Jl3d-Device v-if="deviceif" v-show="deviceShow" ref="Jl3dDevice" :panel-show="deviceShow" @closedevice3dview="jlmap3dmodel" />
<modify-time v-if="datie" ref="modifySysTime" />
<set-time ref="setTime" @ConfirmSelectBeginTime="start" />
<member-manage ref="memberManage" />
</div>
</template>
<script>
@ -35,6 +36,8 @@ import Jl3dDevice from '@/views/jlmap3d/device/jl3ddevice';
import { clearSimulation, ranAsPlan, exitRunPlan} from '@/api/simulation';
import { getToken } from '@/utils/auth';
import { Notification } from 'element-ui';
import MemberManage from './memberManage/membersManage';
export default {
name:'SimulationMenu',
components: {
@ -45,7 +48,8 @@ export default {
ModifyTime,
// Equipment,
ContectUs,
Jl3dDevice
Jl3dDevice,
MemberManage
// StatusIcon
},
props: {

View File

@ -98,20 +98,29 @@ export default {
return this.$store.state.training.roles;
}
},
mounted() {
let currentType = '';
if (this.datie) {
currentType = 'datie';
} else {
currentType = 'subway';
watch: {
'store.state.training.roles': function (val) {
this.initTerminalList();
}
this.terminalMap[currentType].forEach(item => {
if (item.roleList.includes(this.roles)) {
this.terminalList.push(item);
}
});
},
mounted() {
this.initTerminalList();
},
methods:{
initTerminalList() {
let currentType = '';
if (this.datie) {
currentType = 'datie';
} else {
currentType = 'subway';
}
console.log(this.roles, '------init');
this.terminalMap[currentType].forEach(item => {
if (item.roleList.includes(this.roles)) {
this.terminalList.push(item);
}
});
},
noEvent(index) {
this.active = index;
},