<template>
|
<el-container>
|
<el-aside style="width: auto; height: auto;">
|
<el-card class="box-card">
|
<div slot="header" class="linefix">
|
<span>输送线</span>
|
<div :class="['lineStatus', stationValue.status ? 'device-status-0' : 'device-status-1']"></div>
|
</div>
|
<div class="choosefix">
|
<el-select v-model="lineValue" placeholder="请选择" @change="handleLineChange('item', $event)">
|
<el-option v-for="item in lineOptions" :key="item.id" :label="item.text"
|
:value="item.id"></el-option>
|
</el-select>
|
<el-select v-model="stationValue" placeholder="请选择" style="margin-top: 10px;" filterable
|
value-key="stationNum">
|
<el-option v-for="item in listStationsData" :key="item.id" :label="item.stationNum"
|
:value="item">
|
</el-option>
|
</el-select>
|
</div>
|
<div class="lineValuefix">
|
<el-form label-position="left" label-width="80px">
|
<el-form-item label="任务号">
|
<el-input v-model="stationValue.taskNo"></el-input>
|
</el-form-item>
|
<el-form-item label="任务类型">
|
<el-select clearable v-model="stationValue.taskType" placeholder="请选择任务类型">
|
<el-option v-for="(item, index) in dl('TaskTypeEnum')" :key="index"
|
:value="Number(item.value)" :label="`${item.name} [${item.value}]`"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="起始工位">
|
<el-input v-model="stationValue.startLocatNo"></el-input>
|
</el-form-item>
|
<el-form-item label="目的工位">
|
<el-input v-model="stationValue.endLocatNo"></el-input>
|
</el-form-item>
|
<el-form-item label="托盘码">
|
<el-input v-model="stationValue.palletNo"></el-input>
|
</el-form-item>
|
<el-form-item label="PLC">
|
<el-input v-model="stationValue.plc"></el-input>
|
</el-form-item>
|
<el-form-item label="WCS">
|
<el-input v-model="stationValue.wcs"></el-input>
|
</el-form-item>
|
<el-form-item label="状态">
|
<el-input :value="stationValue.status ? '在线' : '离线'" readonly></el-input>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div class="lineButtonfix">
|
<el-form label-position="left" label-width="80px">
|
<el-form-item>
|
<el-button @click="openDialog">设置</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
</el-card>
|
</el-aside>
|
<el-main style="padding: 0 0 0 5px;">
|
<div class="card-container">
|
<el-card class="other-box-card" v-for="deviceInfo in listStackingMachineData" :key="deviceInfo.id">
|
<div slot="header" class="linefix">
|
<span>{{ deviceInfo.text }}</span>
|
<div
|
:class="['lineStatus', { 'device-status-0': deviceInfo.status === true }, { 'device-status-1': deviceInfo.status === false }]">
|
</div>
|
</div>
|
<div class="otherValuefix">
|
<el-form label-position="left" label-width="80px">
|
<el-form-item label="任务号">
|
<el-input v-model="deviceInfo.taskNo"></el-input>
|
</el-form-item>
|
<el-form-item label="任务类型">
|
<el-select clearable="" v-model="deviceInfo.taskType" placeholder="请选择状态">
|
<el-option v-for="(item, index) in dl('TaskTypeEnum')" :key="index"
|
:value="Number(item.value)" :label="`${item.name} [${item.value}] `" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="起始工位">
|
<el-input v-model="deviceInfo.startLocatNo"></el-input>
|
</el-form-item>
|
<el-form-item label="目的工位">
|
<el-input v-model="deviceInfo.endLocatNo"></el-input>
|
</el-form-item>
|
<el-form-item label="托盘码">
|
<el-input v-model="deviceInfo.palletNo"></el-input>
|
</el-form-item>
|
<el-form-item label="PLC">
|
<el-input v-model="deviceInfo.plc"></el-input>
|
</el-form-item>
|
<el-form-item label="WCS">
|
<el-input v-model="deviceInfo.wcs"></el-input>
|
</el-form-item>
|
<el-form-item label="状态">
|
<el-input :value="deviceInfo.status ? '在线' : '离线'" readonly></el-input>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div class="otherButtonfix">
|
<el-form label-position="left">
|
<el-form-item>
|
<el-button @click="write(deviceInfo)">写入</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
</el-card>
|
</div>
|
</el-main>
|
<setting ref="settingDialogRef" :title="title" v-model:listStationsData="listStationsData"
|
v-model:stationValue="stationValue" />
|
</el-container>
|
</template>
|
|
<script lang="ts" setup>
|
import { ref, onMounted } from 'vue';
|
import { listWcsDevice, writeValue } from '/@/api/wcs/wcsDevice';
|
import { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
|
import { listWcsPlc } from '/@/api/wcs/wcsPlc';
|
import { ElMessageBox, ElMessage } from 'element-plus';
|
import setting from '/@/views/device/deviceMonitor/component/setting.vue'
|
import { signalR,stopConnection } from './signalR';
|
//连接signalR 监听变更
|
onMounted(async () => {
|
signalR.off('PublicPlcDevice');
|
signalR.on('PublicPlcDevice', (data: any) => {
|
//todo 需要测试
|
if (data.type == 0) {
|
var index = listStackingMachineData.value.findIndex(s => s.id == data.id);
|
if (index !== -1) {
|
listStackingMachineData.value.splice(index, 1, data);
|
}
|
}
|
else if (data.type == 1) {
|
lineOptions.value.forEach(s => {
|
var index = stations.value[s.id].findIndex(s => s.id == data.id);
|
if (index !== -1) {
|
stations.value[s.id].splice(index, 1, data);
|
}
|
});
|
if (stationValue.value.id == data.id) {
|
stationValue.value = data;
|
}
|
}
|
});
|
});
|
|
const stations = ref<any>([]);
|
const listStationsData = ref<any>([]);
|
const listStackingMachineData = ref<any>([]);
|
const lineOptions = ref<any>([]);
|
const lineValue = ref(1);
|
const title = ref<string>('');
|
const stationValue = ref<any>({
|
taskNo: '',
|
taskType: '',
|
startLocatNo: '',
|
endLocatNo: '',
|
plc: '',
|
wcs: '',
|
status: false
|
});
|
const settingDialogRef = ref();
|
// 打开打印页面
|
const openDialog = async () => {
|
settingDialogRef.value.openDialog(stationValue);
|
}
|
const write = async (row: any) => {
|
await writeValue(row);
|
ElMessage.success('写入成功!');
|
}
|
// 查询操作
|
const handleQuery = async () => {
|
const listplc = await listWcsPlc({ type: 1 });
|
lineOptions.value = listplc.data.result;
|
lineValue.value = listplc.data.result[0].id;
|
const res = await listWcsDevice();
|
listStackingMachineData.value = res.data.result.filter(s => s.type == 0);
|
const listConveyorLineData = res.data.result.filter(s => s.type == 1);
|
listplc.data.result.forEach(s => {
|
stations.value[s.id] = listConveyorLineData.filter(c => c.plcId === s.id)
|
});
|
if (stations.value[lineValue.value].length > 0) {
|
listStationsData.value = stations.value[lineValue.value];
|
stationValue.value = listStationsData.value[0];
|
}
|
else {
|
listStationsData.value = [];
|
stationValue.value = {
|
stationNum: '',
|
taskNo: '',
|
taskType: '',
|
startLocatNo: '',
|
endLocatNo: '',
|
plc: '',
|
wcs: '',
|
status: false
|
};
|
}
|
title.value = listStationsData.value[0].text;
|
};
|
|
handleQuery();
|
|
const handleLineChange = (field: string, value: number) => {
|
listStationsData.value = stations.value[value];
|
title.value = lineOptions.value.filter(s => s.id == value)[0].text;
|
if (listStationsData.value.length > 0)
|
stationValue.value = listStationsData.value[0];
|
};
|
|
</script>
|
|
<style scoped>
|
.text {
|
font-size: 14px;
|
}
|
|
.el-form-item--small {
|
margin-bottom: 10px;
|
}
|
|
.el-button {
|
background-color: #fff;
|
border-color: #fff;
|
color: #000000;
|
}
|
|
.linefix {
|
border-bottom: 1px solid rgb(197, 195, 195);
|
display: flex;
|
align-items: center;
|
height: 30px;
|
position: relative;
|
}
|
|
.lineStatus {
|
position: absolute;
|
right: 0;
|
height: 20px;
|
width: 20px;
|
border-radius: 50%;
|
background-color: #67C23A;
|
}
|
|
.choosefix {
|
width: 100%;
|
padding: 10px;
|
border-bottom: 1px solid rgb(197, 195, 195);
|
}
|
|
.box-card {
|
width: 100%;
|
max-width: 280px;
|
background: linear-gradient(135deg, #66ccff, #3399ff);
|
border-radius: 10px;
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
color: #fff;
|
}
|
|
.lineValuefix {
|
width: 100%;
|
padding: 10px;
|
border-bottom: 1px solid rgb(197, 195, 195);
|
}
|
|
.lineButtonfix {
|
width: 100%;
|
display: flex;
|
justify-content: space-between;
|
padding: 10px;
|
}
|
|
.otherValuefix {
|
width: 100%;
|
padding: 10px;
|
border-bottom: 1px solid rgb(197, 195, 195);
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
/* Optional, for spacing between form items */
|
}
|
|
.card-container {
|
display: grid;
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
gap: 10px;
|
}
|
|
.other-box-card {
|
box-sizing: border-box;
|
background: linear-gradient(135deg, #66ccff, #3399ff);
|
border-radius: 10px;
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
color: #fff;
|
display: flex;
|
flex-direction: column;
|
height: auto;
|
/* Ensure card height adjusts based on content */
|
}
|
|
.otherButtonfix {
|
width: 100%;
|
display: flex;
|
justify-content: center;
|
padding: 10px;
|
}
|
|
.device-status-0 {
|
background-color: #67C23A;
|
}
|
|
.device-status-1 {
|
background-color: red;
|
}
|
|
.linefix span {
|
color: #fff;
|
}
|
</style>
|