Vue.component("watch-rgv-card", {
|
template: `
|
<div class="mc-root">
|
<div class="mc-toolbar">
|
<div class="mc-title">RGV监控</div>
|
<div class="mc-search">
|
<input class="mc-input" v-model="searchRgvNo" placeholder="请输入RGV号" />
|
<button type="button" class="mc-btn mc-btn-ghost" @click="getRgvStateInfo">查询</button>
|
</div>
|
</div>
|
|
<div v-if="!readOnly" class="mc-control-toggle">
|
<button type="button" class="mc-btn mc-btn-ghost" @click="openControl">
|
{{ showControl ? '收起控制中心' : '打开控制中心' }}
|
</button>
|
</div>
|
|
<div v-if="showControl" class="mc-control">
|
<div class="mc-control-grid">
|
<label class="mc-field">
|
<span class="mc-field-label">RGV号</span>
|
<input class="mc-input" v-model="controlParam.rgvNo" placeholder="例如 1" />
|
</label>
|
<label class="mc-field">
|
<span class="mc-field-label">源点</span>
|
<input class="mc-input" v-model="controlParam.sourcePos" placeholder="输入源点" />
|
</label>
|
<label class="mc-field mc-span-2">
|
<span class="mc-field-label">目标点</span>
|
<input class="mc-input" v-model="controlParam.targetPos" placeholder="输入目标点" />
|
</label>
|
<div class="mc-action-row">
|
<button type="button" class="mc-btn" @click="controlCommandTransport">取放货</button>
|
<button type="button" class="mc-btn mc-btn-ghost" @click="controlCommandMove">移动</button>
|
<button type="button" class="mc-btn mc-btn-soft" @click="controlCommandTaskComplete">任务完成</button>
|
</div>
|
</div>
|
</div>
|
|
<div class="mc-collapse">
|
<div
|
v-for="item in displayRgvList"
|
:key="item.rgvNo"
|
:class="['mc-item', { 'is-open': isActive(item.rgvNo) }]"
|
>
|
<button type="button" class="mc-head" @click="toggleItem(item)">
|
<div class="mc-head-main">
|
<div class="mc-head-title">{{ item.rgvNo }}号RGV</div>
|
<div class="mc-head-subtitle">轨道位 {{ orDash(item.trackSiteNo) }} | 任务 {{ orDash(item.taskNo) }}</div>
|
</div>
|
<div class="mc-head-right">
|
<span :class="['mc-badge', 'is-' + getStatusTone(item)]">{{ getStatusLabel(item) }}</span>
|
<span class="mc-chevron">{{ isActive(item.rgvNo) ? '▾' : '▸' }}</span>
|
</div>
|
</button>
|
|
<div v-if="isActive(item.rgvNo)" class="mc-body">
|
<div class="mc-detail-grid">
|
<div v-for="entry in buildDetailEntries(item)" :key="entry.label" class="mc-detail-cell">
|
<div class="mc-detail-label">{{ entry.label }}</div>
|
<div class="mc-detail-value">{{ entry.value }}</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<div v-if="displayRgvList.length === 0" class="mc-empty">当前没有可展示的RGV数据</div>
|
</div>
|
|
<div class="mc-footer">
|
<button type="button" class="mc-page-btn" :disabled="currentPage <= 1" @click="handlePageChange(currentPage - 1)">上一页</button>
|
<span>{{ currentPage }} / {{ totalPages }}</span>
|
<button type="button" class="mc-page-btn" :disabled="currentPage >= totalPages" @click="handlePageChange(currentPage + 1)">下一页</button>
|
</div>
|
</div>
|
`,
|
props: {
|
param: { type: Object, default: function () { return {}; } },
|
items: { type: Array, default: null },
|
autoRefresh: { type: Boolean, default: true },
|
readOnly: { type: Boolean, default: false }
|
},
|
data: function () {
|
return {
|
rgvList: [],
|
activeNames: "",
|
searchRgvNo: "",
|
showControl: false,
|
controlParam: {
|
rgvNo: "",
|
sourcePos: "",
|
targetPos: ""
|
},
|
pageSize: 12,
|
currentPage: 1,
|
timer: null
|
};
|
},
|
computed: {
|
sourceList: function () {
|
return Array.isArray(this.items) ? this.items : this.rgvList;
|
},
|
filteredRgvList: function () {
|
var keyword = String(this.searchRgvNo || "").trim();
|
if (!keyword) {
|
return this.sourceList;
|
}
|
return this.sourceList.filter(function (item) {
|
return String(item.rgvNo) === keyword;
|
});
|
},
|
displayRgvList: function () {
|
var start = (this.currentPage - 1) * this.pageSize;
|
return this.filteredRgvList.slice(start, start + this.pageSize);
|
},
|
totalPages: function () {
|
return Math.max(1, Math.ceil(this.filteredRgvList.length / this.pageSize) || 1);
|
}
|
},
|
watch: {
|
items: function () {
|
this.afterDataRefresh();
|
},
|
param: {
|
deep: true,
|
immediate: true,
|
handler: function (newVal) {
|
if (newVal && newVal.rgvNo && newVal.rgvNo !== 0) {
|
this.focusRgv(newVal.rgvNo);
|
}
|
}
|
}
|
},
|
created: function () {
|
MonitorCardKit.ensureStyles();
|
if (this.autoRefresh) {
|
this.timer = setInterval(this.getRgvStateInfo, 1000);
|
}
|
},
|
beforeDestroy: function () {
|
if (this.timer) {
|
clearInterval(this.timer);
|
this.timer = null;
|
}
|
},
|
methods: {
|
orDash: function (value) {
|
return MonitorCardKit.orDash(value);
|
},
|
getStatusLabel: function (item) {
|
return MonitorCardKit.deviceStatusLabel(item && item.deviceStatus);
|
},
|
getStatusTone: function (item) {
|
return MonitorCardKit.statusTone(this.getStatusLabel(item));
|
},
|
isActive: function (rgvNo) {
|
return String(this.activeNames) === String(rgvNo);
|
},
|
toggleItem: function (item) {
|
var next = String(item.rgvNo);
|
this.activeNames = this.activeNames === next ? "" : next;
|
},
|
focusRgv: function (rgvNo) {
|
this.searchRgvNo = String(rgvNo);
|
var index = this.filteredRgvList.findIndex(function (item) {
|
return String(item.rgvNo) === String(rgvNo);
|
});
|
this.currentPage = index >= 0 ? Math.floor(index / this.pageSize) + 1 : 1;
|
this.activeNames = String(rgvNo);
|
},
|
afterDataRefresh: function () {
|
if (this.currentPage > this.totalPages) {
|
this.currentPage = this.totalPages;
|
}
|
if (this.activeNames) {
|
var exists = this.filteredRgvList.some(function (item) {
|
return String(item.rgvNo) === String(this.activeNames);
|
}, this);
|
if (!exists) {
|
this.activeNames = "";
|
}
|
}
|
},
|
handlePageChange: function (page) {
|
if (page < 1 || page > this.totalPages) {
|
return;
|
}
|
this.currentPage = page;
|
},
|
getRgvStateInfo: function () {
|
if (this.$root && this.$root.sendWs) {
|
this.$root.sendWs(JSON.stringify({
|
url: "/rgv/table/rgv/state",
|
data: {}
|
}));
|
}
|
},
|
setRgvList: function (res) {
|
if (res && res.code === 200) {
|
this.rgvList = res.data || [];
|
this.afterDataRefresh();
|
}
|
},
|
openControl: function () {
|
this.showControl = !this.showControl;
|
},
|
buildDetailEntries: function (item) {
|
return [
|
{ label: "编号", value: this.orDash(item.rgvNo) },
|
{ label: "工作号", value: this.orDash(item.taskNo) },
|
{ label: "模式", value: this.orDash(item.mode) },
|
{ label: "状态", value: this.orDash(item.status) },
|
{ label: "轨道位", value: this.orDash(item.trackSiteNo) },
|
{ label: "是否有物", value: MonitorCardKit.yesNo(item.loading) },
|
{ label: "故障代码", value: this.orDash(item.warnCode) },
|
{ label: "故障描述", value: this.orDash(item.alarm) },
|
{ label: "扩展数据", value: this.orDash(item.extend) }
|
];
|
},
|
postControl: function (url, payload) {
|
$.ajax({
|
url: baseUrl + url,
|
headers: {
|
token: localStorage.getItem("token")
|
},
|
contentType: "application/json",
|
method: "post",
|
data: JSON.stringify(payload),
|
success: function (res) {
|
if (res && res.code === 200) {
|
MonitorCardKit.showMessage(this, res.msg || "操作成功", "success");
|
} else {
|
MonitorCardKit.showMessage(this, (res && res.msg) || "操作失败", "warning");
|
}
|
}.bind(this)
|
});
|
},
|
controlCommandTransport: function () {
|
this.postControl("/rgv/command/transport", this.controlParam);
|
},
|
controlCommandMove: function () {
|
this.postControl("/rgv/command/move", this.controlParam);
|
},
|
controlCommandTaskComplete: function () {
|
this.postControl("/rgv/command/taskComplete", this.controlParam);
|
}
|
}
|
});
|