<template>
|
<div class="monitor-panel-agv">
|
<!-- 状态 -->
|
<div class="states">
|
<div class="state" v-for="state in states" :key="state.id">
|
<div class="num">{{ state.count }}</div>
|
<div class="text">{{ state.text }}</div>
|
</div>
|
</div>
|
<!-- 操作 -->
|
<div class="buttons">
|
<Button type="primary" @click="onEnabled">使能AGV</Button>
|
<Button type="primary" @click="onFrozenAll">冻结全场交通</Button>
|
</div>
|
<!-- 列表 -->
|
<div class="list" ref="list">
|
<div class="header">
|
<div class="tips">选中:{{ checkedLength }}</div>
|
<div class="search">
|
<Input
|
icon="ios-search"
|
placeholder="search"
|
v-model="keyword"
|
@on-enter="search"
|
@on-click="search"
|
/>
|
</div>
|
</div>
|
<Table
|
:columns="columns"
|
:data="list"
|
size="small"
|
@on-selection-change="onSelectionChange"
|
ref="table"
|
>
|
<template #checkbox="{ row }">
|
<Checkbox v-model="row.selected"></Checkbox>
|
</template>
|
<template #state="{ row }">
|
<span v-if="row.state == 'IDLE'">就绪</span>
|
<span v-if="row.state == 'UNKNOWN'">未知</span>
|
<span v-if="row.state == 'UNAVAILABLE'">不可用</span>
|
<span v-if="row.state == 'ERROR'">故障</span>
|
<span v-if="row.state == 'EXECUTING'">调度中</span>
|
<span v-if="row.state == 'CHARGING'">充电中</span>
|
</template>
|
<template #integrationLevel="{ row }">
|
<span v-if="row.integrationLevel == 'TO_BE_UTILIZED'"
|
>加入调度状态</span
|
>
|
<span v-if="row.integrationLevel == 'TO_BE_IGNORED'">忽视车辆</span>
|
<span v-if="row.integrationLevel == 'TO_BE_NOTICED'"
|
>选中车辆位置</span
|
>
|
<span v-if="row.integrationLevel == 'TO_BE_RESPECTED'"
|
>维持车辆当前位置</span
|
>
|
</template>
|
<template #action="{ row }">
|
<div class="action" @click="showAGVModal(row.name)">
|
<Icon type="md-information" size="20" />
|
<br />
|
<span>详情</span>
|
</div>
|
</template>
|
</Table>
|
</div>
|
<MonitorModalAGV
|
v-model="AGVModalVisible"
|
:selectedAGVName="selectedAGVName"
|
></MonitorModalAGV>
|
</div>
|
</template>
|
|
<script>
|
import { webConfig, checkAdmin } from "@/utils";
|
import HttpRequest from "@/api/request";
|
import MonitorModalAGV from "@/components/monitor/modals/agv";
|
export default {
|
name: "MonitorPanelAGV",
|
components: {
|
MonitorModalAGV,
|
},
|
data() {
|
return {
|
httpRequest: new HttpRequest(webConfig.apiUrl),
|
states: [
|
{
|
id: "total",
|
text: "总数",
|
count: 0,
|
},
|
{
|
id: "idle",
|
text: "就绪",
|
count: 0,
|
},
|
{
|
id: "executing",
|
text: "调度中",
|
count: 0,
|
},
|
{
|
id: "charging",
|
text: "充电中",
|
count: 0,
|
},
|
{
|
id: "unavailable",
|
text: "不可用",
|
count: 0,
|
},
|
{
|
id: "error",
|
text: "故障",
|
count: 0,
|
},
|
{
|
id: "unknown",
|
text: "未知",
|
count: 0,
|
},
|
],
|
columns: [
|
{
|
type: "selection",
|
align: "center",
|
width: 40,
|
},
|
{
|
title: "名称",
|
key: "name",
|
width: 100,
|
},
|
{
|
title: "电量",
|
key: "energyLevel",
|
width: 80,
|
},
|
{
|
title: "状态",
|
slot: "state",
|
width: 100,
|
},
|
{
|
title: "环境等级",
|
slot: "integrationLevel",
|
},
|
{
|
title: "操作",
|
slot: "action",
|
width: 50,
|
},
|
],
|
list: [],
|
AGVModalVisible: false,
|
selectedAGVName: "",
|
selection: [],
|
keyword: "",
|
isAdmin: checkAdmin(),
|
};
|
},
|
computed: {
|
checkedLength() {
|
return this.selection.length;
|
},
|
},
|
methods: {
|
onSelectionChange(selection) {
|
this.selection = selection;
|
},
|
onEnabled() {
|
if (!this.isAdmin) return;
|
if (this.selection.length == 0)
|
return this.$Message.warning("未选择车辆");
|
var names = this.selection.map((s) => s.name);
|
names.forEach((name) => {
|
this.httpRequest
|
.post(`vehicles/enable/${name}`)
|
.then(() => {
|
this.$Message.success("操作成功");
|
})
|
.catch((err) => {
|
this.$Message.error({ content: err, duration: 10 });
|
});
|
});
|
},
|
onFrozenAll() {
|
if (!this.isAdmin) return;
|
if (this.selection.length == 0)
|
return this.$Message.warning("未选择车辆");
|
var names = this.selection.map((s) => s.name);
|
names.forEach((name) => {
|
this.httpRequest
|
.post(`vehicles/disable/${name}`)
|
.then(() => {
|
this.$Message.success("操作成功");
|
})
|
.catch((err) => {
|
this.$Message.error({ content: err, duration: 10 });
|
});
|
});
|
},
|
notImplemented() {
|
this.$Message.info({
|
background: true,
|
content: "方法未实现",
|
duration: 10,
|
closable: true,
|
});
|
},
|
showAGVModal(name) {
|
this.selectedAGVName = name;
|
this.AGVModalVisible = true;
|
},
|
loadData() {
|
this.httpRequest
|
.get("vehicles")
|
.then((res) => {
|
console.log(res);
|
// 总数
|
this.states.find((s) => s.id == "total").count = res.length;
|
// 就绪
|
this.states.find((s) => s.id == "idle").count = res.filter(
|
(r) => r.state == "IDLE"
|
).length;
|
// 调度中
|
this.states.find((s) => s.id == "executing").count = res.filter(
|
(r) => r.state == "EXECUTING"
|
).length;
|
// 充电中
|
this.states.find((s) => s.id == "charging").count = res.filter(
|
(r) => r.state == "CHARGING"
|
).length;
|
// 不可用
|
this.states.find((s) => s.id == "unavailable").count = res.filter(
|
(r) => r.state == "UNAVAILABLE"
|
).length;
|
// 故障
|
this.states.find((s) => s.id == "error").count = res.filter(
|
(r) => r.state == "ERROR"
|
).length;
|
// 未知
|
this.states.find((s) => s.id == "unknown").count = res.filter(
|
(r) => r.state == "UNKNOWN"
|
).length;
|
|
// 列表
|
var list = [];
|
list = res.map((r) => {
|
return {
|
name: r.name,
|
energyLevel: r.energyLevel,
|
state: r.state,
|
integrationLevel: r.integrationLevel,
|
};
|
});
|
this.list = list;
|
})
|
.catch((err) => {
|
this.$Message.error({ content: err, duration: 10 });
|
});
|
},
|
search() {
|
this.$refs.table.selectAll(false);
|
let index = 0;
|
this.list.forEach((l, i) => {
|
if (l.name.toLowerCase().indexOf(this.keyword.toLowerCase()) > -1) {
|
this.$refs.table.toggleSelect(i);
|
index = i;
|
}
|
});
|
let scrollTop = index * 40.5;
|
this.$refs.list.scrollTop = scrollTop;
|
},
|
},
|
mounted() {
|
this.loadData();
|
|
if (this.interval) clearInterval(this.interval);
|
this.interval = setInterval(() => {
|
this.loadData();
|
}, 5 * 1000);
|
},
|
beforeDestroy() {
|
if (this.interval) clearInterval(this.interval);
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.monitor-panel-agv {
|
height: 100%;
|
.states {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
justify-content: space-around;
|
margin: 11px 0;
|
.state {
|
width: 65px;
|
padding: 8px;
|
text-align: center;
|
color: #2d8cf0;
|
border: 1px solid #2d8cf0;
|
border-radius: 5px;
|
.num {
|
font-size: 16px;
|
font-weight: bold;
|
}
|
.text {
|
font-size: 12px;
|
}
|
}
|
}
|
.buttons {
|
.ivu-btn {
|
margin-right: 6px;
|
}
|
}
|
.list {
|
height: calc(100% - 104px);
|
overflow: auto;
|
.header {
|
margin-bottom: 3px;
|
.tips {
|
float: left;
|
font-size: 12px;
|
line-height: 38px;
|
}
|
.search {
|
float: right;
|
width: 200px;
|
}
|
&:after {
|
content: "";
|
display: table;
|
clear: both;
|
}
|
}
|
.action {
|
height: 100%;
|
display: inline-block;
|
cursor: pointer;
|
padding: 0 5px;
|
border-radius: 5px;
|
&:hover {
|
color: #fff;
|
background-color: #2db7f5;
|
}
|
}
|
}
|
}
|
</style>
|